二叉搜索树(BST)定义:
-
这颗树可以为空,也可以不空。左子树的值
小于
跟结点的值,右子树的值大于
跟结点的值,并且左右子树都是二叉搜索树。 -
由于二叉搜索树有左小右大的有序特征,对二叉搜索树进行
中序遍历
,将得到一个从小到大
的序列 -
非递归查找的时间复杂度为:
T(n)=O(h)
,h为树的高度,如果是一个完美二叉的话,T(n)=O(log~2n)
,如果是一个斜二叉树的话,T(n)=O(n)
,n为结点个数;
二叉搜索树的查找
递归查找
Position Find(BinTree BST,ElemenType X)
{
if(!BST) return NULL;
if(X>BST->Data)
return Find(BST->Right,X);
else if(X<BST->Data)
return Find(BST->Left,X);
else
return BST;
}
非递归查找
Position Find(BinTree BST,ElemenType X)
{
while(BST)
{
if(X>BST->Data)
BST=BST->Right;
else if(X<BST->Data)
BST=BST->Left;
else
break;
}
return BST;
}
查找二叉搜索树的最大值和最小值
- 最左边的结点一定是最小的值,最右边的结点一定是最大的值
Position Findmin(BinTree BST)
{
if(BST)//判断一下跟结点是否为空
while(BST->Left)
BST=BST->Left;
return BST;
}
Position Findmax(BinTree BST)
{
if(BST)//判断跟结点是否为空
while(BST->Right)
BST=BST->Right;
return BST;
}
二叉搜索树的插入
- 先查找准备插入的元素
X
在二叉搜索树中的位置 - 如果找到一个数等于
X
的话,直接结束查找操作 - 如果没有元素与X相等,查找终止的位置就是X插入的位置,终止的位置就是结点为空的位置
- 通过递归结果的接收,将插入的数据连接在原来的树上
BinTree Insert(BinTree BST,ElemenType X)
{
if(!BST)//如果结点为空 ,赋值
{
BST=(BinTree)malloc(sizeof(struct TNode));
BST->Data=X;
BST->Left=BST->Right=NULL;
}
else//开始找要插入元素的位置
{
if(X>BST->Data)//将X插入BST的右边
BST->Right=Insert(BST->Right,X);//使用BST->Right接收非常重要,如果不接收就不会连到一起
else if(X<BST->Data)//将X插入BST的左边
BST->Left=Insert(BST->Left,X);
else//X已经存在,就什么都不用做
}
}
二叉搜索树的删除
要考虑三种情况
- 要删除的结点是叶结点,直接删除,并让其父结点指针指向为NULL;
- 要删除的结点只有一个左孩子或右孩子,将父结点的指针指向要删除结点的孩子,删除要删除的结点
- 要删除的结点有左孩子和右孩子,用另一结点替代被删除结点,替代的结点可以是要删除结点左子树的最大值或右子树的最小值
BinTree Delete(ElemenType X,BinTree BST)
{
Position Tmp;
if(!BST)
printf("要删除结点未找到");
else if(X<BST->Data)//左子树递归
BST->Left=Delete(X,BST->Left);
else if(X>BST->Data)//右子树递归
BST->Right=Delete(X,BST->Right);
else//找到要删除的结点
if(BST->Left&&BST->Right)//要删除结点的左右子树都存在
{
// 找要删除结点左子树的最大值或找右子树的最小值并与要删除结点替换
Tmp=FindMin(BST->Right); //还可以改成Tmp=FindMax(BST->Left)
BST->Data=Tmp->Data;
BST->Right=Delete(BST->Data,BST->Right);//删除用于替换的那个值
}
else//被删除结点有一个或无子结点
{
Tmp=BST;
if(!BST->Left)//有右孩子或无子结点
BST=BST->Right;//直接赋值
else if(!BST->Right)//有左孩子或无子结点
BST=BST->Left;
free(Tmp);
}
return Tmp;
}