[Data Structure] 二叉搜索树(Binary Search Tree) - 笔记
2016-07-28 01:37
465 查看
1. 二叉搜索树,可以用作字典,或者优先队列。
2. 根节点 root 是树结构里面唯一一个其父节点为空的节点。
3. 二叉树搜索树的属性:
假设 x 是二叉搜索树的一个节点。如果 y 是 x 左子树里面的一个节点,则 y.key <= x.key。如果 y 是 x 右子树里面的一个节点,则 x.key <= y.key。
4. 通过一次中序遍历 ( inorder tree walk ),可以将二叉搜索树的元素按照排好的顺序输出。例子如下
5. 二叉搜索树不仅支持搜索操作,还支持查找最小值、最大值、后继节点( successor )、前驱节点( predecessor )
搜索,通过递归能轻易实现搜索操作.
迭代版代码如下
最小值,是最左边的节点
最大值,是最右边的节点
节点 x 的后继节点,是值在树结构中比 x 大的最小节点。
后继节点有两种情况
a. 当节点 x 有右子树,则后继节点为右子树中最小值。
b. 当节点 x 没有右子树并有后继节点,则 x 的后继节点为 x 的某个祖先节点,该祖先节点满足其左子节点也是 x 的祖先节点。也就是说,从 x 往 root 的父节点路径查找,第一个向右拐的目标节点(即,父节点),就是后继节点。
前驱节点和后继节点的查找思路相似。
6. 插入节点 x,有两个步骤:1) 搜索合适插入的位置 2) 插入元素。代码如下
7. 删除节点 x ,有下面三种情况
a. 没有子节点,则直接删除
b. 仅有一个子节点,则用子节点代替待删除节点。
c. 有两个子节点,则找到 x 的后继节点 y。y 必然在 x 的右子树里面最左边的节点。然后,用 y 覆盖 x, 删除 y 原来的节点。由于 y 是右子树里最左边的节点,所以没有左字节,有或者没有右子节点,此时便是 a 或 b 的情况。
下面是根据上面逻辑写代码实现。和书本的版本比起来,代码行数多些,不过可读性较好。
参考资料
Binary search tree. Removing a node, algolist
12 Binary Search Trees, Introduction to algorithms
第 12 章 二叉搜索树,《算法导论》
2. 根节点 root 是树结构里面唯一一个其父节点为空的节点。
3. 二叉树搜索树的属性:
假设 x 是二叉搜索树的一个节点。如果 y 是 x 左子树里面的一个节点,则 y.key <= x.key。如果 y 是 x 右子树里面的一个节点,则 x.key <= y.key。
4. 通过一次中序遍历 ( inorder tree walk ),可以将二叉搜索树的元素按照排好的顺序输出。例子如下
INORDER-TREE-WALK(x) if x != NIL INORDER-TREE-WALK(x.left) print x.key INORDER-TREE-WALK(x.right)
5. 二叉搜索树不仅支持搜索操作,还支持查找最小值、最大值、后继节点( successor )、前驱节点( predecessor )
搜索,通过递归能轻易实现搜索操作.
TREE-SEARCH(X) if x == NIL or k == x.key return x if k < x.key return TREE-SEARCH(x.left) else return TREE-SEARCH(x.right)
迭代版代码如下
ITERATIVE-TREE-SEARCH(x, k) while x != NIL and k != x.key if x < x.key x = x.left else x = x.right return x
最小值,是最左边的节点
TREE-MINIMUM(x) while x.left != NIL x = x.left return x
最大值,是最右边的节点
TREE-MAXIMUM(x) while x.right != NIL x = x.right return x
节点 x 的后继节点,是值在树结构中比 x 大的最小节点。
后继节点有两种情况
a. 当节点 x 有右子树,则后继节点为右子树中最小值。
b. 当节点 x 没有右子树并有后继节点,则 x 的后继节点为 x 的某个祖先节点,该祖先节点满足其左子节点也是 x 的祖先节点。也就是说,从 x 往 root 的父节点路径查找,第一个向右拐的目标节点(即,父节点),就是后继节点。
TREE-SUCCESSOR(x) if x.right != NIL return TREE-MINIMUM(x) y = x.p while y != NIL and x == y.right x = y y = y.p return y
前驱节点和后继节点的查找思路相似。
6. 插入节点 x,有两个步骤:1) 搜索合适插入的位置 2) 插入元素。代码如下
TREE-INSERT(T, z) y = NIL x = T.root while(x != NIL) y = x if z.key < x.key x = x.left else x = x.right z.p = y if y == NIL T.root = z elseif z.key < y.key y.left = z else y.right = z
7. 删除节点 x ,有下面三种情况
a. 没有子节点,则直接删除
b. 仅有一个子节点,则用子节点代替待删除节点。
c. 有两个子节点,则找到 x 的后继节点 y。y 必然在 x 的右子树里面最左边的节点。然后,用 y 覆盖 x, 删除 y 原来的节点。由于 y 是右子树里最左边的节点,所以没有左字节,有或者没有右子节点,此时便是 a 或 b 的情况。
下面是根据上面逻辑写代码实现。和书本的版本比起来,代码行数多些,不过可读性较好。
TREE-DELETE(node) if node.left == NIL && node.right == NIL node.parent = NIL return if node.left != NIL && node.right != NIL newN = TREE-MINIMUM(node.right) node.key = newN.key TREE-DELETE(newN) return if node.left != NIL p = node.p s = node.left p.left = s s.p = p node.p = NIL node.left = NIL if node.right != NIL p = node.p s = node.right p.right = s s.p = p node.p = NIL node.right = NIL
参考资料
Binary search tree. Removing a node, algolist
12 Binary Search Trees, Introduction to algorithms
第 12 章 二叉搜索树,《算法导论》
相关文章推荐
- linux入门第二天
- 性能之多线程
- vue.js表单数据双向绑定
- Android自定义View-登录界面
- 1. Two Sum
- 本地WinSCP上传文件到腾讯云服务器显示Permission Denied
- Python办公
- Android之为什么一个线程只有一个Handler,Looper
- 求两个数的最大公约数。
- FMS配置小结
- Android中的Viewpager ------ 01(ViewPager的简单使用)
- POJ1740之构造博弈
- 前端日志
- (25)HTML标签详解之<form><input><label><fieldset><legend>
- 多线程
- 9. Palindrome Number
- 8. String to Integer (atoi)
- 码神之奇妙之旅3
- mysql插入表中的中文显示为乱码或问号的解决方法
- 进程间通信方式总结