本文是MOOC浙大数据结构课程的笔记
课程详细地址
什么是二叉搜索树
二叉搜索树(BST,Binary Search Tree),也称二叉排序树或者二叉查找树
二叉搜索树:一颗二叉树,可以为空;如果不为空,满足以下性质:
- 非空左子树的所有键值小于其根结点的键值。
- 非空右子树的所有键值大于其根结点的键值。
- 左、右子树都是二叉搜索树。
查找操作Find
Position Find(ElementType X,BinTree BST)
{
if(!BST)return NULL; // 查找失败
if(x > BST->Data)
return Find(X,BST->Right); // 向右子树移动
else if(x < BST->Data)
return Find(X,BST->Left); // 向左子树移动
else
return BST;
}
上面的代码属于“尾递归”,由于非递归函数执行效率高,可将“尾递归”函数改为迭代函数
Position IterFind(ElementType X,BinTree BST)
{
while(BST){
if(X > BST->Data)
BST=BST->Right; // 向右子树移动
else if(X < BST->Data)
BST=BST->Left; // 向左子树移动
else
return BST;
}
return NULL; // 查找失败
}
很明显,查找效率决定于树的高度
查找最大和最小元素
查找最小元素的递归函数
Position FindMin(BinTree BST)
{
if(!BST)return NULL; // 空的二叉搜索树,查找失败
else if(!BST->Left)
return BST; // 找到最左叶结点并返回
else
return FindMin(BST->Left);
}
查找最大元素的迭代函数
Position FindMin(BinTree BST)
{
if(BST)
while(BST->Right)
BST=BST->Right; // 沿着右分支继续查找,找到最右叶结点并返回
return BST;
}
二叉树搜索树的插入
插入的关键在于找到插入的位置
二叉搜索树的插入算法
BinTree Insert(ElementType X,BinTree BST)
{
if(!BST){
BST=malloc(sizeof(struct TreeNode));
BST->Data=X;
BST->Left=BST->Right=NULL;
}else{
if(X < BST->Data)
BST->Left=Insert(X,BST->Left); // 向右子树移动
else if(X > BST->Data)
BST->Right=Insert(X,BST->Right); // 向右子树移动
}
return BST;
}
二叉树搜索树的删除
删除需要考虑三种情况:
- 删除的是叶结点,直接删除,并且修改其父结点指针
- 要删除的结点只有一个孩子结点,将其父结点的指针指向要删除结点的孩子结点
- 要删除的结点有左、右两颗子树:用另一个结点替代被删除节点
- 右子树的最小元素
- 左子树的最大元素
BinTree Delete(ElementType 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); // 在右子树找最小的元素填充删除结点
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 BST;
}