目录
一、二叉搜索树的概念
二叉搜索树又被称为二叉排序树,它要么是一棵空树,要么是具有以下性质的树形结构:
(1)如果他的左子树不为空,则左子树上的所有节点的值都小于根节点
(2)如果他的右子树不为空,则右子树上的所有节点的值都大于根节点
(3)他的左右子树都是一颗二叉搜索树
二、二叉搜索树的基本操作
int a[] = {8, 3, 1, 10, 6, 4, 7, 14, 13};用来创建树的序列
(1)搜索二叉树的定义
以下就是搜索二叉树的框架啦,我们后续的函数都是在这个基础上进行添加的
(2)搜索二叉树的插入
插入的具体过程如下:
a. 树为空,则直接新增节点,赋值给root指针
b. 树不空,按二叉搜索树性质查找插入位置,插入新节点
(3)搜索二叉树的查找
查找的具体过程如下:
a、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。
b、最多查找高度次,走到到空,还没找到,这个值不存在。
(4)搜索二叉树的中序遍历
搜索二叉树的中序遍历是一个非常有用的东西,因为在搜索二叉树中他们的节点都是按照一定规律存放的,而中序遍历恰好能够升序遍历
可以看到,我们这里给了两个函数,他们本来是只需要一个的。但是为了在类外面访问的方便(不用传递根节点了)我们选择了public成员函数去调用private成员函数,从而达到方便调用的目的。
(5)搜索二叉树的删除
搜索二叉树的删除可以说是比前面的几个函数都要难!因为他涉及到许多的特例讨论。
首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点
看起来有待删除节点有4中情况,实际情况a可以与情况b或者c合并起来,因此真正的删除过程如下:
情况b:删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除
情况c:删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除
情况d:在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点
中,再来处理该结点的删除问题--替换法删除
三、用递归的思路写增删查
(1)查找
(2)插入
注意这里的形参列表!我们看到root是一个pNode的引用类型,这是为什么呢?我们在之前的插入中还用了一个指针去记录父节点,然后再去连接新节点和父亲,但是这里使用了引用之后就不会存在这个问题了。
在传入root->_pleft的时候,他就是下一层调用处root的别名!我们在下层函数中更新了root的指向,就相当于改变了该处的root->_pleft于是这两个节点就连接起来了。从而达到了我们不需要记录父亲节点就能够连接新节点的麻烦。
但是为什么不能再循环中使用这个方法呢?因为c++的引用规定了必须在初始化的时候赋值,也就是说引用仅仅只能赋值一次(但是后续值的修改也会影响原变量),在递归调用中,每一层看起来都是root,但是由于他们存在于不同的栈帧中,所以他们是不同的变量root(即还是只赋值了一次)。但是在while循环结构中,因为只有一个cur变量在运动,如果是引用的话不能修改其指向,所以在循环中仍然只能使用一步步迭代的方法。