数据结构复习 【7.3.1 树表的查找--二叉排序树】

引言

当表的插入和删除操作频繁时,为了维护表的有序性,我们需要移动表中的很多记录——可以改用动态查找表,使用几种特殊的树(二叉排序树、平衡二叉树、红黑树、B+、B-、键树等),使表结构在查找过程中动态生成。

一、二叉排序树(二叉搜索树、查找树)

1.定义

二叉排序树或是空树、或是满足如下性质的二叉树:
(1)若其左子树非空,则左子树上所有节点的值均小于根节点的值。
(2)若其右子树非空,则右子树上所有节点的值均大于等于根节点的值。
(3)其左右子树本身又一棵二叉排序树

2.性质

中序遍历非空的二叉排序树得到的数据元素序列,是一个按关键字排列递增有序序列。

3.查找操作

查找的关键字等于根结点,查找成功
否则,(1)若小于根结点,查其左子树 (2)如大于根结点,查其右子树
之后在左右子树上的操作类似,查找失败返回空指针。

3.1.相关代码
3.1.1 二叉树排序树的存储结构
typedef struct{
    
    
	KeyType key;  //关键字项
	InfoType otherinfo;   //其他数据域
} ElemType;
typedef struct BSTNode{
    
    
	ElemType data;     //数据域
	struct BSTNode *lchild,*rchild; //左右孩子指针
}BSTNode,*BSTree;

BSTtree T;  //定义二叉排序树T
3.1.2 递归查找算法

【算法思想】
(1)若二叉树为空,查找失败,返回空指针
(2)若二叉树非空,将给定值key与根节点的关键字T->data.key进行比较:
      ① key 等于 T->data.key,查找成功,返回根节点地址
      ② key 小于 T->data.key,进一步查找左子树
      ② key 大于 T->data.key,进一步查找右子树

BSTree SearchBST(BSTree T,KeyType key){
    
    
	if( (!T) || key ==  T->data.key) return T;
	else if(key < T->data.key)
		return SearchBST(T->lchild,key); //在左子树中继续查找
	else return SearchBST(T->rchild,key); //在右子树中继续查找
}
3.2.效率分析

含有n个节点的二叉排序树,其平均查找长度树的形态有关。
(1)最好情况:完全二叉树,变成判定树,与折半查找相同ASL= log2(N+1) -1,O(log2N)
(2)最坏情况:一开始就有序,变成右斜树,与顺序查找形同ASL=(N+1)/2,O(n)

4.插入操作

若二叉排序树为空,则插入节点作为根节点插入到空树中
否则,继续在其左、右子树上查找
      ① 树中已有,不再插入
      ② 树中没有,查找并插入至某个结点的左孩子或右孩子处。

5.生成操作

(1)一个无序序列可以通过构造二叉排序树而变成一个有序序列,构造树的过程是对无序序列进行排序的过程
(2)插入的结点均为叶子结点,因此无须移动其他节点相当于在有序序列上插入记录无需移动其他记录。
(3)关键字的输入顺序不同,建立的二叉排序树不同。

6.删除操作

删除后要保证所得二叉树仍然满足二叉排序树的性质不变。
由于中序遍历二叉排序树可以得到一个递增有序的序列,那么删除一个结点相当于删除有序序列中的一个结点。

6.1 删除叶子结点

直接删除该结点,将双亲结点中对应指针域的值改为空即可

6.2 删除含有左子树(或右子树)的结点

用其左子树(或右子树)替换自身结点即可。

6.3 删除含有左、右子树的结点

直接用中序遍历的前驱节点后继节点来替换自身结点,其中:
(1)前驱节点:左子树中最大的节点。(即当前结点-> 左孩子 -> 右孩子 -> 右孩子 …
(1)后继节点:右子树中最小的节点。(即当前结点-> 右孩子 -> 左孩子 -> 左孩子 …

猜你喜欢

转载自blog.csdn.net/qq_41794040/article/details/108080659