1. 概念:

Binary-search tree(BST)是一颗二叉树,每个树上的节点都有<=1个父亲节点,ROOT节点没有父亲节点。同时每个树上的节点都有[0,2]个孩子节点(left child AND right child)。每个节点都包含有各自的KEY值以及相应的satellite data。其中KEY是几种BST基本操作的主要操作对象。

2. BST的特别性质:

BST任何一颗子树上的三个节点left, parent, right. 满足条件left.key<parent.key<=right.key,一颗典型的BST如下图所示:

              

观察之后不难发现如果对BST进行PREORDER walk(先序遍历),得到:2, 5, 5, 6, 7, 8 刚好是升序排列。

P.S 所谓PREORDER walk,就是要访问以ROOT为根的树,先要访问ROOT.left, 然后访问ROOT, 最后访问ROOT.right。

用pseudocode的形式的话,就是这样:

PREORDER-WALK(x)

1 if(x!=NIL) 

2   PREORDER-WALK(x.left)

3   print x.key

4   PREORDER-WALK(x.right)

3. BST的几种基本操作:

SEARCH, MINIMUM, MAXIMUM, PREDECESSOR, SUCCESSOR, INSERT, and DELETE.

2.1 SEARCH:

TREE-SEARCH(x, k)
INPUT: BST ROOT node, value k.
OUPUT: node in BST whose key equals to k
1 if(x==NIL) OR (k==x.key)
2   return x
3 if(k<x.key)
4   return TREE-SEARCH(x.left, k)
5 else return TREE-SEARCH(x.right, k)

算法解释:当我们要找到key值为k的节点在BST中的位置,我们一般调用上述函数TREE-SEARCH(ROOT, k)(ROOT为BST的根节点)。如果ROOT节点的key值等于k,则我们要找的节点就是根节点ROOT。如果不是,根据BST的特殊性质:

left.key<parent.key<=right.key

我们比较当前节点的key值,如果current.key<k,则要在当前节点的左子树中查找,反之,则在右子树中查找。[line3-line5]

2.2 MINIMUM:

TREE-MINIMUM(x)
INPUT: BST ROOT node
OUTPUT: the smallest key in BST
1 if(x==NIL) return;
2 while(x.left!=NIL)
3   x=x.left
4 return x.key

算法解释:一个BST的最左叶子节点的key值就是BST所有key值中最小的。这个根据BST的特殊性质很容易推导出来:

因为 left.key < parent.key < parent.key < .... < root.key

有了MINIMUM算法,MAXIMUM算法也就有了:

2.3 MAXIMUM:

TREE-MAXIMUM(x)
INPUT: BST ROOT node
OUTPUT: the smallest key in BST
1 if(x==NIL) return;
2 while(x.right!=NIL)
3   x=x.right
4 return x.key

2.4 SUCCESSOR:

TREE-SUCCESSOR(x)
INPUT: arbitray node x in BST
OUTPUT: x's successor node
1 if(x.right!=NIL)
2   TREE-MINIMUM(x.right)
3 y=x.parent
4 while(y!=NIL AND y.left==x)
5   x=y
6   y=y.parent
7 return y

这里说明一下SUCCESSOR的含义,x的SUCCESSOR满足x.key<=x.SUCCESSOR.key,并且x.SUCCESSOR.key是距离x.key最近的值,即x.SUCCESSOR.key是x.key的最小上限(minimum ceiling)

算法思想:因为在BST中,有x.key<=x.right.key。所以如果某BST的节点x有右孩子节点(x.right!=NIL),则利用TREE-MINIMUM在x的右子树中查找即可。如果x不存在右孩子,则检查x是否有父亲节点并且x必须是父亲节点的左孩子,只有这样才有parent.key>parent.left.key。但找到x的parent就结束了吗,还没有,就像TREE-MINIMUM函数一样,我们需要逐层查找,当找到符合条件的parent后,我们递归的继续检查parent节点有没有parent.parent节点符不符合上述条件。知道访问到的parent节点不符合该条件为止

2.5 INSERT:

TREE-INSERT(T, z)
1 y=NIL
2 x=T.ROOT
3 while(x!=NIL)
4   y=x
5   if(z.key<x.key)
6     x=x.left
7   else x=x.right
8 z.p=y
9 if(y==NIL) T.ROOT=z
10 if(z.key<y.key) y.left=z
11 else y.right=z

用一张图来解释该算法:

   

虚线指向的key值为13的节点是即将要插入BST的点,其他的点已经在BST上。可以看到从ROOT节点出发,根据“左小右大”规则,我们很快找到了key值为15的节点,因为13<15,所以检查‘15’节点是否有左孩子,结果是没有,所以把13放到15的左孩子节点处。我们可以想象如果要插入的节点key是16会怎么样?同样的,我们还是找到‘15’节点,但是16>15,所以继续往‘右’查找,找到‘17’,因为16<17,看17有没有左孩子节点,没有,所以会把‘16’放到‘17’的左孩子节点处。

2.6 TRANSPLANT:

TRANPLANT(T, u, v)
1 if (u.parent==NIL) T.ROOT=v
2 else if(u==u.parent;.left) u.parent.left=v
3 else u.parent.right=v
4 if(v!=NIL) v.parent=u.parent

还是用一张图来展示比较清晰:

2.7 DELETE:

TREE-DELETE(T, z)
1 if z.left==NIL
2 TRANSPLANT(T, z, z.right)
3 else if z.right == NIL
4 TRANSPLANT(T, z, z.left)
5 else y=TREE-MINIMUM(z.right)
6 if y.parent!=z
7 TRANSPLANT(T, y, y.right)
8 y.right=z.right
9 y.right.parent=y
10 TRANSPLANT(T, z, y)
11 y.left=z.left
12 y.left.parent=y

DELETE算法相对来说比较麻烦一些,需要考虑的情况要多一些。因为要在删除BST的某一节点后仍能维持BST的基本性质。假设要删除的节点是z,z的key值为k。根据“左小右大”原则,z.left.key<k<=z.right.key.如果这时候吧z删了,谁来接替z的位置呢并且保证解体之后的新BST满足性质呢?方法我们可以根据性质来推导:我们要找到一个除了z以外的节点在BST中,该节点假设为P,那么P.key要大于z.left.key并且P.key>=z.right.key,实际上很明显的,唯一符合要求的就是z的SUCCESSOR。

如果z只有左子树或者只有右子树,那么问题就很简单,使z的左孩子或者右孩子来顶替z的位置即可。如果z的左子树和右子树都存在,那么问题稍微复杂一点,我们要在BST上找到z的SUCCESSOR。如此一来,这个问题又变成我们之前讨论的SUCCESSOR问题了,总共有两种情形:

第一种情形:z的右孩子就是我们要找的z的SUCCESSOR,那我们就直接TRANSPLANT移植以z.right为根的子树到z的位置中去。

第二种情形:z的右孩子不是我们要找的z的SUCCESSOR,那我们就从z.right出发,‘深入’寻找知道找到z的SUCCESSOR,假设为Q。

那么我们让Q成为z.right的父亲节点,并且让以Q为根的右子树(因为是根据“最左原则”找到的Q,Q要么是以z.right为根的left-most叶子节点,要么Q只有右子树。)取代Q的位置。最后让Q取代z的位置。。。很绕。。。还是见图吧。

   

算法导论学习-binary search tree的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. 72【leetcode】经典算法- Lowest Common Ancestor of a Binary Search Tree(lct of bst)

    题目描述: 一个二叉搜索树,给定两个节点a,b,求最小的公共祖先 _______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5 例如: 2,8 - ...

  3. 【LeetCode-面试算法经典-Java实现】【109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)】

    [109-Convert Sorted List to Binary Search Tree(排序链表转换成二叉排序树)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 ...

  4. 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)

    议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...

  5. 将百分制转换为5分制的算法 Binary Search Tree ordered binary tree sorted binary tree Huffman Tree

    1.二叉搜索树:去一个陌生的城市问路到目的地: for each node, all elements in its left subtree are less-or-equal to the nod ...

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

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

  7. 算法与数据结构基础 - 二叉查找树(Binary Search Tree)

    二叉查找树基础 二叉查找树(BST)满足这样的性质,或是一颗空树:或左子树节点值小于根节点值.右子树节点值大于根节点值,左右子树也分别满足这个性质. 利用这个性质,可以迭代(iterative)或递归 ...

  8. 二叉查找树(binary search tree)详解

    二叉查找树(Binary Search Tree),也称二叉排序树(binary sorted tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于 ...

  9. [Data Structure] 二叉搜索树(Binary Search Tree) - 笔记

    1. 二叉搜索树,可以用作字典,或者优先队列. 2. 根节点 root 是树结构里面唯一一个其父节点为空的节点. 3. 二叉树搜索树的属性: 假设 x 是二叉搜索树的一个节点.如果 y 是 x 左子树 ...

随机推荐

  1. Hive(转)

    Hive分区表 在Hive Select查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作.有时候只需要扫描表中关心的一部分数据,因此建表时引入了partition概念.分区表指的是在创建表时指 ...

  2. 扩展pl0编译器设计——总述

    所谓编译器,实际上就是我们编程时将输入的高级语言代码转换成相应的目标代码,从而实现将目标代码转换成汇编码的一种过渡工具. 这种工具根据具体情况不同,可以将不同的高级语言代码转换成不同的目标代码,例如将 ...

  3. noj [1482] 嘛~付钱吧!(完全背包)

    http://ac.nbutoj.com/Problem/view.xhtml?id=1482 [1482] 嘛~付钱吧! 时间限制: 1000 ms 内存限制: 65535 K 问题描述 大白菜带着 ...

  4. 如何创建phpinfo查看php信息?

    创建一个简单的文本文档并命名为phpinfo.php   代码如下: <?php phpinfo(); ?>   将上面的代码写入并保存该文档,通过浏览器访问这个文件即可显示PHP信息  

  5. r个有标志的球放进n个不同的盒子里,要求无一空盒,问有多少种不同的分配方案?

           由题意可知道r>=n,我原来想的是先取n个全排列,剩下的r-n个每个有n中选择,所以结果是n!*n^(r-n).经满神猜测,这样是会重复的.比如说,1到5个球,ABC三个盒子,ms ...

  6. Oracle SQL tuning 步骤

    Oracle SQL tuning 步骤 SQL是的全称是Structured Query Language(结构化查询语言).SQL是一个在80年代中期被使用的工业标准数据库查询语言.不要把SQL语 ...

  7. Ajax.BeginForm返回方法OnSuccess

    在MVC3里面——程序集 System.Web.Mvc.dll, v4.0.30319有这么一个Ajax.BeginForm异步登录验证的类型,我们在下面给出一个例子:在登录页面Logion.csht ...

  8. SPRING IN ACTION 第4版笔记-第四章ASPECT-ORIENTED SPRING-012-AOP总结

    1.AOP是面向对象编程的有力补充,它可以让你把分散在应用中的公共辅助功能抽取成模块,以灵活配置,减少了重复代码,让类更关注于自身的功能

  9. VCL+FMX 双剑合壁编程

    VCL 是经典,FMX 是新生,新生事物总会带来一些好玩新奇的东西.舍弃经典是浪费,不了解新生事物是等死,那么我们来一个二合一双剑合壁又如何呢? 要双剑合壁,就得投些机,取些巧.由于 Delphi / ...

  10. Java之String,StringBuffer,StringBuilder类

    在 java 语言中, 用来处理字符串的的类常用的有 3 个: String.StringBuffer.StringBuilder. 它们的异同点: 1) 都是 final 类, 都不允许被继承; 2 ...