二叉树
2016-03-07 15:37
232 查看
原文链接:/article/4778089.html
若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
任意节点的左、右子树也分别为二叉查找树。
没有键值相等的节点(no duplicate nodes)。
该方法实现有迭代和递归两种。
递归的方式实现如下:
迭代如下:
以下是递归的版本:
以查找Floor为例,我们首先将key和root元素比较,如果key比root的key小,则floor值一定在左子树上;如果比root的key大,则有可能在右子树上,当且仅当其右子树有一个节点的key值要小于等于该key;如果和root的key相等,则floor值就是key。根据以上分析,Floor方法的代码如下,Ceiling方法的代码类似,只需要把符号换一下即可:
作者: yangecnu(yangecnu’s Blog on 博客园)
出处:http://www.cnblogs.com/yangecnu/
本作品由yangecnu 创作,采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。 欢迎转载,但任何转载必须保留完整文章,在显要地方显示署名以及原文链接。如您有任何疑问或者授权方面的协商,请 给我留言。
如何判断一棵树是否为二叉排序树?
二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
任意节点的左、右子树也分别为二叉查找树。
没有键值相等的节点(no duplicate nodes)。
实现
在实现中,我们需要定义一个内部类Node,它包含两个分别指向左右节点的Node,一个用于排序的Key,以及该节点包含的值Value,还有一个记录该节点及所有子节点个数的值Number。public class BinarySearchTreeSymbolTable<TKey, TValue> : SymbolTables<TKey, TValue> where TKey : IComparable<TKey>, IEquatable<TValue> { private Node root; private class Node { public Node Left { get; set; } public Node Right { get; set; } public int Number { get; set; } public TKey Key { get; set; } public TValue Value { get; set; } public Node(TKey key, TValue value, int number) { this.Key = key; this.Value = value; this.Number = number; } } ... }
查找
查找操作和二分查找类似,将key和节点的key比较,如果小于,那么就在Left Node节点查找,如果大于,则在Right Node节点查找,如果相等,直接返回Value。该方法实现有迭代和递归两种。
递归的方式实现如下:
public override TValue Get(TKey key) { TValue result = default(TValue); Node node = root; while (node != null) { if (key.CompareTo(node.Key) > 0) { node = node.Right; } else if (key.CompareTo(node.Key) < 0) { node = node.Left; } else { result = node.Value; break; } } return result; }
迭代如下:
public TValue Get(TKey key) { return GetValue(root, key); } private TValue GetValue(Node root, TKey key) { if (root == null) return default(TValue); int cmp = key.CompareTo(root.Key); if (cmp > 0) return GetValue(root.Right, key); else if (cmp < 0) return GetValue(root.Left, key); else return root.Value; }
插入
插入和查找类似,首先查找有没有和key相同的,如果有,更新;如果没有找到,那么创建新的节点。并更新每个节点的Number值,代码实现如下:public override void Put(TKey key, TValue value) { root = Put(root, key, value); } private Node Put(Node x, TKey key, TValue value) { //如果节点为空,则创建新的节点,并返回 //否则比较根据大小判断是左节点还是右节点,然后继续查找左子树还是右子树 //同时更新节点的Number的值 if (x == null) return new Node(key, value, 1); int cmp = key.CompareTo(x.Key); if (cmp < 0) x.Left = Put(x.Left, key, value); else if (cmp > 0) x.Right = Put(x.Right, key, value); else x.Value = value; x.Number = Size(x.Left) + Size(x.Right) + 1; return x; } private int Size(Node node) { if (node == null) return 0; else return node.Number; }
最大最小值
二叉查找树中,最左和最右节点即为最小值和最大值,所以我们只需迭代调用即可。public override TKey GetMax() { TKey maxItem = default(TKey); Node s = root; while (s.Right != null) { s = s.Right; } maxItem = s.Key; return maxItem; } public override TKey GetMin() { TKey minItem = default(TKey); Node s = root; while (s.Left != null) { s = s.Left; } minItem = s.Key; return minItem; }
以下是递归的版本:
public TKey GetMaxRecursive() { return GetMaxRecursive(root); } private TKey GetMaxRecursive(Node root) { if (root.Right == null) return root.Key; return GetMaxRecursive(root.Right); } public TKey GetMinRecursive() { return GetMinRecursive(root); } private TKey GetMinRecursive(Node root) { if (root.Left == null) return root.Key; return GetMinRecursive(root.Left); }
Floor和Ceiling
查找Floor(key)的值就是所有<=key的最大值,相反查找Ceiling的值就是所有>=key的最小值以查找Floor为例,我们首先将key和root元素比较,如果key比root的key小,则floor值一定在左子树上;如果比root的key大,则有可能在右子树上,当且仅当其右子树有一个节点的key值要小于等于该key;如果和root的key相等,则floor值就是key。根据以上分析,Floor方法的代码如下,Ceiling方法的代码类似,只需要把符号换一下即可:
public TKey Floor(TKey key) { Node x = Floor(root, key); if (x != null) return x.Key; else return default(TKey); } private Node Floor(Node x, TKey key) { if (x == null) return null; int cmp = key.CompareTo(x.Key); if (cmp == 0) return x; if (cmp < 0) return Floor(x.Left, key); else { Node right = Floor(x.Right, key); if (right == null) return x; else return right; } }
作者: yangecnu(yangecnu’s Blog on 博客园)
出处:http://www.cnblogs.com/yangecnu/
本作品由yangecnu 创作,采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。 欢迎转载,但任何转载必须保留完整文章,在显要地方显示署名以及原文链接。如您有任何疑问或者授权方面的协商,请 给我留言。
相关文章推荐
- 正则表达式问题
- PAT (Basic Level)1049. 数列的片段和
- 【转】Android系统中的.apk文件和dex文件
- 学习进度总结
- Redis Sentinel高可用架构
- 面向对象之里氏替换原则
- const用法
- LeetCode 8 String to Integer (atoi)
- 12306验证码破解思路分享
- 文章标题
- 博弈sg函数
- 阿里巴巴发布《2015移动安全漏洞年报》
- 快速排序(解析及代码实现)
- Android APP长期运行于后台,重启后如何避免异常
- Google Protocol Buffer 的使用和原理
- iOS mask 层 UIBezierPath path 放大
- vim命令图解
- 好雨云的微服务架构实践
- 欢迎使用CSDN-markdown编辑器
- iOS开发多线程篇—GCD的基本使用