1:概念

二叉搜索树也叫二叉排序树,它支持的操作有:SEARCH, MINIMUM, MAXIMUM, PREDECESSOR, SUCCESSOR, INSERT, DELETE。所以,一颗二叉搜索树既可以作为一个字典,又可以作为一个优先队列。

二叉搜索树的基本操作时间与这棵树的高度成正比。二叉搜索树的高度可以从Ө(lgn) 到 Ө(n)。

二叉搜索树可以用链表来存储,每个节点包括:key,卫星数据,left, right, p指针。

二叉搜索树的性质是:设x为二叉查找树中的一个节点,如果y是x的左子树中的一个节点,则y.key <= x.key;如果y是x的右子树中的一个节点,则y.key >= x.key。这个性质对树中的每个节点都成立。对于一组值,可以用不同的二叉搜索树表示。如下图:

二:按序输出

中序遍历二叉搜索树,就可以将树中的元素按序输出。中序遍历的时间是:Ө(n)。

三:查询操作

二叉搜索树除了支持SEARCH操作之外,还支持MINIMUM, MAXIMUM, SUCCESSOR,  PREDECESSOR的查询操作。这些操作都可以在O(h)时间内完成,h为二叉搜索树的高度

1:SEARCH

递归算法:

TREE-SEARCH(x, k)

If x == null or k == x.key

Return x

If k < x.key

Return TREE-SEARCH(x.left, k)

Else

Return TREE-SEARCH(x.right, k)

迭代算法:对于大多数计算机来说,迭代版本的效率要高

ITERATIVE-TREE-SEARCH(x, k)

While x !=  NULL and k !=  x.key

If k < x.key

x = x.left

Else x = x.right

Return x

2:MAXIMUM, MINIMUM

找最小元素,就是从树根开始,一直沿着左子树向下寻找,直到找到一个节点,它没有左孩子。

找最大元素,就是从树根开始,一直沿着右子树向下寻找,直到找到一个节点,它没有右孩子。

TREE-MINIMUM(x)

while x.left != NULL

x= x.left

return x

TREE-MAXIMUM(x)

while x.right != NULL

x=x. right

return x

3:SUCCESSOR, PREDECESSOR

给定一个二叉搜索树中的一个节点,有时候需要按中序遍历的次序查找它的后继或者前驱。

节点x的后继就是大于x.key的最小关键字的节点。如果x的右子树非空,则x的后继就是x的右子树中的最小节点。如果x的右子树为空,则需要从x开始向上寻找,直到找到x的一个祖先,他有左孩子。这个祖先就是x的后继。

TREE-SUCCESSOR(x)

If x.right != NULL

Return TREE-MINIMUM(x.right)

Y= x.p

While y != NULL and x== y.right

X = y

Y = y.p

Return y

如果节点中不含有p指针的话,则是:

TREE-SUCCESSOR2(T, x)

If x.right != NULL

Return TREE-MINIMUM(x.right)

Y = T.root

Cur = NULL

While y != NULL and x.key  != y.key

If x.key < y.key

Cur = y

Y = y.left

Else

Y = y.right

Return cur

节点x的前驱就是小于x.key的最大关键字的节点。如果x的左子树非空,则x的后继就是x的左子树中的最大节点。如果x的左子树为空,则需要从x开始向上寻找,直到找到x的一个祖先,他有右孩子。这个祖先就是x的前驱。

TREE-PREDECESSOR(x)

If x.left != NULL

Return TREE-MAXIMUM(x.left)

Y= x.p

While y != NULL and x== y.left

X = y

Y = y.p

Return y

如果节点中不含有p指针的话,则是:

TREE- PREDECESSOR (T,x)

If x.left != NULL

Return TREE- MAXIMUM (x. left)

Y = T.root

Cur = NULL

While y != NULL and  x.key != y.key

If x.key > y.key

Cur = y

Y = y. right

Else

Y = y.left

Return cur

四:插入和删除

插入和删除操作都会改变二叉搜索树,但是同时要保证二叉搜索树的性质

插入和删除操作的运行时间为O(h),h为二叉搜索树的高度

1:插入

要插入的新节点都将成为一个叶子节点,插入操作较简单,代码如下:

TREE-INSERT(T, z)

Y = NULL

X = T.root

While x != NULL

Y= x

If z.key < x.key

X= x.left

Else  x = x.right

z.p = y

if y == NULL

T.root = z

Else if z.key < y.key

y.left = x

else

y.right = x

2:删除

删除操作较复杂,需要区分不同的情况:

a:如果z没有孩子节点,则简单的将z删除即可

b:如果z有一个孩子节点,则将孩子节点提升到z的位置上即可

c:如果z有两个孩子,那么需要找到z的后继y,y一定在z的右子树中。如果y是z的右孩子,那么y一定没有左孩子(参见后继算法),此时用y替换z即可;如果y不是z的右孩子,则需要用y的右孩子替换y,然后用y替换z。

如下图:

为了在二叉搜索树中移动子树,定义子过程TRANSPLANT,它用一颗子树替换另一颗子树:

TRANSPLANT(T,u,v)   //用v替换u

If u.p == NULL

T.root = v

Else if u == u.p.left

u.p.left = v

else u.p.right = v

if  v != NULL

v.p = u.p

该过程只是使u的双亲成为v的双亲,并没有处理v的孩子节点的更新,这需要调用者来处理:

TREE-DELETE(T, z)

If z.left == NULL

TRANSPLANT(T, z, z.right)

Else if z.right == NULL

TRANSPLANT(T, z, z.left)

Else y = TREE-MINIMUM(z.right)

If y.p != z

TRANSPLANT(T, y, y.right)

y.right = z.right

y.right.p = y

TRANSPLANT(T, z, y)

y.left = z.left

y.left.p = y

五:随机构建二叉搜索树

二叉搜索树的操作都能在O(h)时间内完成,h是二叉搜索树的高度。在构建二叉搜索树的时候,如果n个关键字是按照递增的顺序插入的话,那么这个树的高度为n-1。这是最坏的情况,所以可以对n个关键字进行随机化:随机构建二叉搜索树为按随机次序插入关键字到一颗初始空树,这里输入关键字排列共有n!种,每个个排列都是等可能的。

一颗有n个不同关键字的随机构件二叉搜索树的期望高度为O(lg n)

算法导论笔记:12二叉搜索树相关推荐

  1. l2-004 这是二叉搜索树吗?_算法学习笔记(45): 二叉搜索树

    二叉搜索树(Binary Search Tree, BST)是一种常用的数据结构,在理想情况下,它可以以 的复杂度完成一系列修改和查询,包括: 插入一个数 删除一个数 查询某数的排名(排名定义为比该数 ...

  2. leetcode算法题--不同的二叉搜索树

    原题链接:https://leetcode-cn.com/problems/unique-binary-search-trees/ 相关题目:leetcode算法题--不同的二叉搜索树 II 1.递归 ...

  3. 算法入门 12.二叉搜索树

    //二叉搜索树 #include<iostream> using namespace std; struct node{int val;node *lch,*rch; };node *in ...

  4. LeetCode刷题笔记 二叉树 二叉搜索树的操作

    669 修剪二叉搜索树 ​ 给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内. ​ 输入是一个二叉查找树和两个整数 ...

  5. 算法:最优二叉搜索树

    算法设计第五次作业part2 1.纸面题:对最优二叉树和矩阵连乘两种算法验证四边形法则,如果符合四边形法则则举几个正例,如果不符合则举几个反例 四边形法则 i<i'j<j'w(i,j)+w ...

  6. 学习笔记:二叉搜索树的验证

    方法一(低效): 最开始想的办法是,先写 求二叉树中最大值的函数,和一个求二叉树中最小值的函数,然后调用这两个函数 写出 验证二叉搜索树的函数(因为要左边小于右边嘛),结果 时间复杂度特别大,老是超时 ...

  7. 算法实验 最优二叉搜索树

    最优二叉搜索树 最优二叉搜索树 问题描述 问题分析 代码 问题描述 二叉搜索树我们都知道,左子树结点的值都小于根结点,右子树结点的值都大于根节点.如果某个结点没有左子树或右子树,那么在对应的位置上加一 ...

  8. 剑指笔记——33.二叉搜索树的后序遍历序列

    题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No. 假设输入的数组的任意两个数字都互不相同. 思路:在这个题中要注意是二叉搜索树,二叉搜索树满足左 ...

  9. 大顶堆删除最大值_算法学习笔记(47): 二叉堆

    堆(Heap)是一类数据结构,它们拥有树状结构,且能够保证父节点比子节点大(或小).当根节点保存堆中最大值时,称为大根堆:反之,则称为小根堆. 二叉堆(Binary Heap)是最简单.常用的堆,是一 ...

最新文章

  1. pku1384---Piggy-Bank(动态规划)
  2. C++ public、protected、private区别
  3. wxWidgets:创建自定义小部件
  4. 线性代数之相似矩阵与二次型基础点
  5. 手机和Linux蓝牙通信,[原创]linux下手机与蓝牙的连接配置
  6. aix系统java堆_浅谈AIX环境下的Java性能调优
  7. [js] 不用 + eval Function 实现加法
  8. android怎样封装,如何封装属于自己的博客网站安卓APP 源码家园
  9. 7-63 情人节 (15 分)(c++stl)
  10. Springboot读取jar包中的MANIFEST.MF文件内容
  11. 字符编码过滤器中对特殊的路径进行特殊处理
  12. 如何把include_type_name的值设置为true
  13. zen-Coding
  14. Adobe Acrobat Pro制作pdf模板
  15. 建议收藏,22个Python迷你项目(附源码)
  16. 大数据Spark(一):框架概述
  17. MongoDB Compass简易教程
  18. LogSeq 表格合并单元格
  19. 跳过wifi认证直接上网
  20. 安卓开发中的 “Android高手” ,需要具备哪些技术?

热门文章

  1. 苦恼的月下老人(最长子序列)by C++
  2. 动物克隆技术应用价值_动物克隆技术及其研究现状
  3. 电脑端,PC端,微信小程序打不开,加载空白,或者提示加载失败
  4. Activity生命周期和启动模式
  5. Mac pro 突然没有办法按住shift打出大写S
  6. 云服务AppId或AppKey和AppSecret生成与使用
  7. Jetson Nano配置YOLOv5并实现FPS=25
  8. keras提取网络中间层输出、中间层特征
  9. getenv putenv setenv和unsetenv详解
  10. webpack使用详解