树中
一.二叉搜索树(BST,Binary Search Tree)
二叉搜索树也称二叉排序树(因为它有一定的顺序在里面)或二叉查找树(因为里面的某些规律方便查找),可以为空。
不为空时的性质:
非空左子树的所有键值小于其根结点的键值;
非空右子树的所有键值大于其根结点的键值;
左,右子树都是二叉搜索树。
既然叫二叉查找树,那我们就来看看它的查找吧!
二叉搜索树的查找
查找过程:我们先从根结点开始,如果为空,则返回NULL;非空的话我们将关键字X进行比较。
若小于根结点的键值,则在左子树进行递归查找,否则就是右子树,这是性质,若相同就返回
该结点的指针。
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 Find(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)//为空,返回NULL
{
return NULL;
}
else if(!BST->Left)//找到最左端结点
{
return BST;
}
else
{
return FindMin(BST->Left);//沿着左分支继续找
}
}
Position FindMax(BinTree BST)
{
if(!BST)//为空,返回NULL
{
return NULL;
}
else if(!BST->Right)//找到最右端结点
{
return BST;
}
else
{
return FindMin(BST->Right);//沿着右分支继续找
}
}
二叉搜索树的插入
其实和Find很相像,因为我们得先找到,才能进行插入,但是我们得注意一点,如果是叶结点,我们得主动申请一个空间,然后在跟其根结点比较,看是放左边,还是右边。
BinTree Insert(ElementType X,BinTree BST)
{
if(!BST)//主动申请
{
BST=(struct TreeNode *)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);
}
else
return BST;
}
}
讲了查找,插入,就该讲删除了吧
二叉搜索树的删除
删除的时候,我们得非常小心,因为我们的结点有三种状态。
叶结点:没有孩子,我们就残忍一点,直接删除,并且修改器父结点的指针为空。
只有一个孩子的结点:将它的父结点直接指向孙子结点,孙子变儿子。
有两个孩子的结点:用另一结点代替删除结点:取右子树最小元素代替或取左子树最大元素代替。孩子多就是麻烦!所以我们会用的之前写的函数!
BinTree Delete(ElementType X,BinTree BST)
{
Position temp;
if(!BST)//失败
{
printf("删除元素未找到");
}
else if(X>BST->data)
{
BST->Right=Delete(X,BST->Right);
}
else if(X<BST->data)
{
BST->Left=Delete(X,BST->Left);
}
else
{
if(BST->Left&&BST->Right)//带两个孩子
{
temp=FindMin(BST->Right);
BST->data=temp->data;
BST->Right=Delete(BSt->data,BST->Right);
}
else
{
temp=BST;
if(!BST->Left)
{
BST=BST->Right;
}
else if(!BST->Right)
{
BST=BST->Left
}
free(temp);
}
}
else
return BST;
}