算法导论(Introduction to Algorithms )— 第十二章 二叉搜索树— 12.1 什么是二叉搜索树

搜索树数据结构支持许多动态集合操作,如search(查找)、minmum(最小元素)、maxmum(最大元素)、predecessor(前驱)、successor(后继)、insert(插入)、delete(删除),这些都是基本操作,可以使用一颗搜索树当做一个字典或者一个优先队列。

12.1、什么事二叉搜索树

二叉搜索树是以一棵二叉树来组织的,可以用一个链表数据结构来表示,也叫二叉排序树、二叉查找树;

其中的每个结点都是一个对象,每个对象含有多个属性(key:该结点代表的值大小,卫星数据:不清楚,left:左孩子结点,right:右孩子结点,p:双亲,貌似是单亲)。

如果某个孩子结点和父结点不存在,则相应属性值为NULL;

根结点是树中唯一父指针为NULL的结点。

二叉搜索树的性质:

设x是二叉搜索树中的一个结点,若y是x左子树中的一个结点,则y.key <= x.key;若y是x右子树中的一个结点,则y.key >= x.key;

通俗讲就是二叉搜索树中的任意一个结点的做孩子结点值不大于该结点,右孩子结点的值不小于改结点。

二叉搜索树的关键字都是按照二叉搜索树性质的方式存储的,即只要一个数是二叉搜索树,则必须满足上述性质。

不同的二叉搜索树可以代表同一组值的集合。

二叉搜索树的性质允许我们通过一个简单递归算法来按序输出二叉搜索树中的所有关键字(遍历时,从根结点开始遍历),根据递归时子树根的关键字与其左右子树关键字输出顺序的不同,分三种便利方式:

若递归遍历时输出的子树根的关键字位于其左子树的关键字和右子树的关键之间,则称为中序遍历。

若递归遍历时输出的子树根的关键字位于其左子树的关键字和右子树的关键之前,则称为先序遍历。

若递归遍历时输出的子树根的关键字位于其左子树的关键字和右子树的关键之后,则称为后序遍历。

中序遍历的简单递归过程为:

middleOrder (x){

if(x != null)

middleOrder (x.left);

print x.key;

middleOrder (x.right);

}

先序遍历的简单递归过程为:

preOrder (x){

if(x != null)

print x.key;

preOrder (x.left);

preOrder (x.right);

}

中序遍历的简单递归过程为:

afterOrder (x){

if(x != null)

afterOrder (x.left);

afterOrder (x.right);

print x.key;

}

举例如下图:

中序遍历分析:

1、根据中序递归的执行过程,可判断从最左下方开始输出,2,5(6的左孩子的关键字,此时为子树根),5,这三个数分别是左孩子,子树根,右孩子,按照中序遍历的定义,则输出顺序为2、5(子树根)、5(右孩子)

2、5、6、7三个类似,输出5、6、7

3、7无左孩子,则直接输出7、8

最后结果为:2、5(6的左孩子的关键字)、5(6的左孩子的右孩子)、6、7、8

先序遍历方式为:根据先序递归的过程,先输出子树根结点,再递归遍历其左子树和右子树结点,结果为:6、5(6的左孩子)、2、5(6的左孩子的右孩子)、7、8

后序遍历方式为:根据后序递归的过程,先输出子树根的左右结点,再输出子树根结点,结果为:2、5(6的左孩子的右孩子)、5、5(6的左孩子)、8、7、6

关键点:可想象递归程序的执行过程,来判断输出结果。

定理:如果x是一棵有n个结点子树的根,那么调用middleOrder(x)需要Θ(n)时间,同理preOrder和afterOrder也是Θ(n)时间。

定理分析:证明该递归算法需要Θ(n)时间,则需要证明Ω(n)<=T(n)<=Ο(n)

遍历单个结点时间假设为常量,则因为需要遍历n个结点,所以T(n)>= Ω(n),即最少需要时间为n的线性函数,系数和常数项省略,Ω简单说表示所需时间的下界。

T(n)<=Ο(n)证明省略。

练习:

12.1-1 对于关键字集合{1、4、5、10、16、17、21},分别画出高度为2、3、4、5、6的二叉搜索树。

分析:如下图:

2、待续,

算法导论(Introduction to Algorithms )— 第十二章 二叉搜索树— 12.1 什么是二叉搜索树

时间: 2024-10-08 22:01:17

算法导论(Introduction to Algorithms )— 第十二章 二叉搜索树— 12.1 什么是二叉搜索树的相关文章

《算法导论》读书笔记之第16章 0-1背包问题—动态规划求解

原文:http://www.cnblogs.com/Anker/archive/2013/05/04/3059070.html 1.前言 前段时间忙着搞毕业论文,看书效率不高,导致博客一个多月没有更新了.前段时间真是有些堕落啊,混日子的感觉,很少不爽.今天开始继续看算法导论.今天继续学习动态规划和贪心算法.首先简单的介绍一下动态规划与贪心算法的各自特点及其区别.然后针对0-1背包问题进行讨论.最后给出一个简单的测试例子,联系动态规划实现0-1背包问题. 2.动态规划与贪心算法 关于动态规划的总结

算法导论 第十章 基本数据类型 &amp; 第十一章 散列表(python)

更多的理论细节可以用<数据结构>严蔚敏 看几遍,数据结构很重要是实现算法的很大一部分 下面主要谈谈python什么实现 10.1 栈和队列 栈:后进先出LIFO 队列:先进先出FIFO python 中使用list实现在这些功能 栈:压栈 append() 退栈   pop() 队列:   入队 append() 出队 pop(0) 栈: >>> stack = list() >>> stack.append(3) >>> stack.ap

《算法导论》读书笔记之第11章 散列表

本章介绍了散列表(hash table)的概念.散列函数的设计及散列冲突的处理.散列表类似与字典的目录,查找的元素都有一个key与之对应,在实践当中,散列技术的效率是很高的,合理的设计散函数和冲突处理方法,可以使得在散列表中查找一个元素的期望时间为O(1).散列表是普通数组概念的推广,在散列表中,不是直接把关键字用作数组下标,而是根据关键字通过散列函数计算出来的.书中介绍散列表非常注重推理和证明,看的时候迷迷糊糊的,再次证明了数学真的很重要.在STL中map容器的功能就是散列表的功能,但是map

算法导论 学习资源

学习的过程会遇到些问题,发现了一些比较好的资源,每章都会看下别人写的总结,自己太懒了,先记录下别人写的吧,呵呵. 1  Tanky Woo的,每次差不多都看他的 <算法导论>学习总结 - 1.前言 <算法导论>学习总结 - 2.第一章 && 第二章 && 第三章 <算法导论>学习总结 - 3.第四章 && 第五章 <算法导论>学习总结 - 4.第六章(1) 堆排序 <算法导论>学习总结 - 5.第六

《算法导论》读书笔记(五)

摘要: 本章介绍了二叉查找树的概念及操作.主要内容包括二叉查找树的性质,如何在二叉查找树中查找最大值.最小值和给定的值,如何找出某一个元素的前驱和后继,如何在二叉查找树中进行插入和删除操作.在二叉查找树上执行这些基本操作的时间与树的高度成正比,一棵随机构造的二叉查找树的期望高度为O(lgn),从而基本动态集合的操作平均时间为θ(lgn). 1.二叉查找树 二叉查找树是按照二叉树结构来组织的,因此可以用二叉链表结构表示.二叉查找树中的关键字的存储方式满足的特征是:设x为二叉查找树中的一个结点.如果

《算法导论》读书笔记(一)

本章是本书的开篇,介绍了什么是算法,为什么要学习算法,算法在计算机中的地位及作用. 算法(algorithm)简单来说就是定义良好的计算机过程,它取一个或一组值作为输入,并产生出一个或一组值作为输出.即算法就是一系列的计算步骤,用来将输入数据转换成输出数据. 书中有一句话非常好: Having a solid base of algorithm knowledge and technique is one characteristic that separates the truly skill

c++ primer plus(第6版)中文版 第十二章编程练习答案

第十二章编程练习答案 12.1根据以下类声明,完成类,并编小程序使用它 //12.1根据以下类声明,完成类,并编小程序使用它 #include <iostream> #include <cstring> using namespace std; class Cow{ char name[20]; char * hobby; double weight; public: Cow(); Cow(const char * nm, const char * ho, double wt);

算法导论--图的存储(邻接表与邻接矩阵)

转载请注明出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51888031 图的存储方法有邻接表.邻近矩阵.邻接多重表.十字链表等.本篇文章介绍两种简单且比较常用的两种方法:邻接表与邻接矩阵方法. 以下面的无向图为例,介绍两种存储方法.有向图的存储方法类似,只是边是单方向,无向图的边可以看做双向. 1.邻接链表法 邻接链表表示法对图中的每个顶点建立一个带头的边链表:第i条链表代表依附于顶点vi所有边信息,若为有向图,则表示

《算法导论》读书笔记(三)

本章介绍了快速排序及其算法分析,快速排序采用的是分治算法思想,对包含n个数的输入数组,最坏情况下运行时间为θ(n^2),但是平均性能相当好,期望的运行时间为θ(nlgn).另外快速排序能够就地排序(我理解是不需要引入额外的辅助空间,每次划分能确定一个元素的具体位置),在虚拟环境中能很好的工作. 1.快速排序的描述 快速排序算法采用的分治算法,因此对一个子数组A[p-r]进行快速排序的三个步骤为: (1)分解:数组A[p...r]被划分为两个(可能为空)子数组A[p...q-1]和A[q+1...