1. 二叉搜索树,可以用作字典,或者优先队列。

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 章 二叉搜索树,《算法导论》

[Data Structure] 二叉搜索树(Binary Search Tree) - 笔记的更多相关文章

  1. 编程算法 - 二叉搜索树(binary search tree) 代码(C)

    二叉搜索树(binary search tree) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉搜索树(binary search tree)能 ...

  2. 二叉搜索树(Binary Search Tree)(Java实现)

    @ 目录 1.二叉搜索树 1.1. 基本概念 1.2.树的节点(BinaryNode) 1.3.构造器和成员变量 1.3.公共方法(public method) 1.4.比较函数 1.5.contai ...

  3. 数据结构 《5》----二叉搜索树 ( Binary Search Tree )

    二叉树的一个重要应用就是查找. 二叉搜索树 满足如下的性质: 左子树的关键字 < 节点的关键字 < 右子树的关键字 1. Find(x) 有了上述的性质后,我们就可以像二分查找那样查找给定 ...

  4. 二叉搜索树(Binary Search Tree)实现及测试

    转:http://blog.csdn.net/a19881029/article/details/24379339 实现代码:  Node.java  //节点类public class Node{ ...

  5. [LeetCode] Split BST 分割二叉搜索树

    Given a Binary Search Tree (BST) with root node root, and a target value V, split the tree into two ...

  6. 自己动手实现java数据结构(六)二叉搜索树

    1.二叉搜索树介绍 前面我们已经介绍过了向量和链表.有序向量可以以二分查找的方式高效的查找特定元素,而缺点是插入删除的效率较低(需要整体移动内部元素):链表的优点在于插入,删除元素时效率较高,但由于不 ...

  7. 二叉搜索树 (BST) 的创建以及遍历

    二叉搜索树(Binary Search Tree) : 属于二叉树,其中每个节点都含有一个可以比较的键(如需要可以在键上关联值), 且每个节点的键都大于其左子树中的任意节点而小于右子树的任意节点的键. ...

  8. BinarySearchTree二叉搜索树的实现

    /* 二叉搜索树(Binary Search Tree),(又:二叉查找树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; ...

  9. 二叉搜索树(BST)---python实现

    github:代码实现 本文算法均使用python3实现 1. 二叉搜索树定义   二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree).   二叉搜 ...

随机推荐

  1. Python开发【第九篇】:HTML (二)

    python[第十四篇]HTML基础 时间:2016-08-08 20:57:27      阅读:49      评论:0      收藏:0      [点我收藏+] 标签: 什么是HTML? H ...

  2. OD: Windows Driver Fuzz

    内核 FUZZ 思路 内核 API  函数:是提供给 Ring3 调用,在 Ring0 完成最终功能的函数.这些函数接收 Ring3 传入的参数,如果处理参数的过程存在问题的话,很有可能成为一个内核漏 ...

  3. Linq101-Join

    using System; using System.Collections.Generic; using System.Linq; namespace Linq101 { internal clas ...

  4. 【转】 NSArray copy 问题

    转自:   http://blog.sina.com.cn/s/blog_6b1e4a060102uz0i.html   好久没写博客了,今天看到同事的代码中用到了 copy 这个 方法,之前也有了解 ...

  5. Puer是一个可以实时编辑刷新的前端服务器

    ##Puer是一个可以实时编辑刷新的前端服务器 确保你安装了nodejs(现在还有没nodejs环境的前端? 拖出去喂狗吧) 使用npm全局安装puer命令 npm install puer -g 输 ...

  6. java学习——网络编程UDP

    UDP 将数据及源和目的封装成数据包中,不需要建立连接 每个数据报的大小限制在64k内 因无连接,是不可靠协议 不需要建立连接,速度快 TCP 建立连接,形成传输数据的通道 在连接中进行大数据量传输 ...

  7. 你好,C++(36)人参再好,也不能当饭吃!6.3 类是如何面向对象的

    6.3  类是如何面向对象的 类作为C++与面向对象思想结合的产物,作为面向对象思想在C++中的载体,它的身上流淌着面向对象的血液.从类成员的构成到类之间的继承关系再到虚函数,到处都体现着面向对象封装 ...

  8. 《C++游戏开发》笔记十四 平滑过渡的战争迷雾(二) 实现:真正的迷雾来了

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9712321 作者:七十一雾央 新浪微博:http:/ ...

  9. 各种开源协议介绍 BSD、Apache Licence、GPL V2 、GPL V3 、LGPL、MIT

    现今存在的开源协议很多,而经过Open Source Initiative组织通过批准的开源协议目前有58种(http://www.opensource.org/licenses /alphabeti ...

  10. LINUX系统安装MYSQL命令,纯手打

    1.下载安装包 wget http://cdn.mysql.com/archives/mysql-5.6/mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz    2. ...