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. log4j 日志的初始化

    log4j 不指定时,log4j 会默认进行初始化,如果想要制定log4j.properties的位置时,可以进行指定: PropertyConfigurator.configure(): 参数里面加 ...

  2. Android开发艺术探索》读书笔记 (12) 第12章 Bitmap的加载和Cache

    第12章 Bitmap的加载和Cache 12.1 Bitmap的高速加载 (1)Bitmap是如何加载的?BitmapFactory类提供了四类方法:decodeFile.decodeResourc ...

  3. 循序渐近学docker---笔记

    1.安装docker 环境:ubuntu 16.04 sudo apt-get install docker.io root@ld-Lenovo-G470:~# docker -vDocker ver ...

  4. Datables wrning(table id='example'):Cannot reinitialise DataTable.

    出现的问题如下所示: Datables wrning(table id='example' Datables object for this table,please pass eithser no ...

  5. java编程思想-注解思维导图

  6. (转)ThinkPHP自定义标签

    第一:在当前应用下的Conf文件夹中config.php加两个配制项:             'TAGLIB_LOAD' => true,//加载标签库打开             'APP_ ...

  7. cxf WebService整理 (基于注解)

    http://blog.csdn.net/zjw10wei321/article/details/39889823

  8. 配置中的address不能重复

    <jaxws:endpoint  implementor="com.service.imp.UserServiceImpl" address="/user" ...

  9. 在iframe里调用parent.func()引出的js函数运行在它们被定义的作用域里,而不是它们被执行的作用域里

    有个document里定义了一个函数func(),同时在document里嵌入了一个iframe,在这个iframe里调用父窗口的方法:parent.func(),本来我以为这个函数的运行环境是在这个 ...

  10. 初涉JavaScript模式 (5) : 原型模式 【一】

    什么是原型模式? 原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象.--引自JavaScript设计模式 我们创建的每一个函数都有一个prototype ...