二叉搜索树:任意两个节点的关键字值不同;若左子树、右子树不空,左子树键值<根节点键值< 右节点键值;左右子树也分别是 二叉搜索树。
性质:以中序遍历二叉 搜索树,那么将会得到一个递增的序列。
关于二叉搜索树的删除:容易理解,二叉搜索树的任意一颗子树的最大元素和最小元素所在的节点的度<=1,既然二叉搜索树以中序遍历时是一个递增的序列,那么删除二叉搜索树的一个节点,相当于在中序遍历序列中删除此节点,那么该节点可以用直接后继(或者直接前继)来替换。
删除的节点可能有两颗非空子树, 也可能最多只有一颗非空子树。如果此节点有两颗非空子树,那么该节点将被其中序遍历的序列的直接后继替换, 直接后继必定是该节点右子树中的最小元素,既然是最小元素,那么其节点的度不会大于1,删除此节点就会 相对容易,这也转换 成删除一个最多有一颗非空子树的 节点。删除 最多有一颗非空子树的节点,只要 用其左子树来替换或者右子树替换即可,如果左子树非空就用左子树替换,否则用右子树替换,这样如果子树均空的情况也被包含进去。
#include<stdio.h>
#include<stdlib.h>
typedef struct entry{
int Key;
int Data;
}Entry;
typedef struct bstnode{
Entry Element;
struct bstnode *LChild,*RChlid;
}BSTNode,*BSTree;
BSTree RecSearchBST(BSTree T,int k)//递归搜索 ,如果搜索到把节点的指针返回
{
if(!T)
return NULL;
if(T->Element.Key==k)
return T;//当前的节点的键值匹配成功
else if(T->Element.Key>k)
return RecSearchBST(T->LChild,k);//k比较小,向左孩子方向搜索
else
return RecSearchBST(T->RChlid,k) ;//k比较大,向右孩子方向搜索
}
int InsertBST(BSTree &T,Entry e)
{
//int key=e.Key;
BSTree temp=T,l;
while(temp)
{
l=temp;//l暂存未变化的temp
if(temp->Element.Key<e.Key)
temp=temp->RChlid;
else if(temp->Element.Key>e.Key)
temp=temp->LChild;
else
{
printf("重复\n");
return 0;
}
}
//至此temp指向一个NULL
temp=(BSTNode*)malloc(sizeof(BSTNode));
temp->LChild=temp->RChlid=NULL;
temp->Element=e;
if(!T)//如果T是空的
T=temp;
else if(l->Element.Key<e.Key)//下面两种情况是T非空
l->RChlid=temp;
else
l->LChild=temp;
return 1;
}
int DeleteBST(BSTree &T,int k)
{
BSTree p=T,q,s,r,c;//p指向待删除的节点,q是p的双亲节点;s,r是在有两颗非空子树的情况下的暂时变量 ;c是最终进行删除操作时的用到的。
while(p&&p->Element.Key!=k)
{
q=p;//q是p的双亲节点
if(k<p->Element.Key)
p=p->LChild;
else
p=p->RChlid;
}
if(!p)
{
printf("不存在");
return 0;
}
if(p->LChild&&p->RChlid)//如果有两颗非空子树
{
s=p->RChlid;//方便找到节点的直接后继
r=p;// 可能s就是其的直接后继,然后将r作为s的父节点
while(s->LChild)
{
r=s;
s=s->LChild;//直到找到最小值
}
p->Element=s->Element;
p=s;q=r;//相当于转换成了最多有一个非空子树的待删除节点
}
//上面的处理可以将有两颗非空子树的节点转换为删除最多有一颗非空子树的节点
if(p->LChild)
c=p->LChild;
else
c=p->RChlid;
//接下来就是准备删除操作了
if(p==T)
T=c;//判断是否为根节点,此步也可以判断q是否为NULL,这需要在定义q时初始化NULL。
else if(p==q->LChild)//接下来就是判断,p是q的左子树还是右子树了
q->LChild=c;
else
q->RChlid=c;
free(p);
return 1;
}
int main()
{
BSTree T=NULL;
Entry a;
a.Data=0;a.Key=1;
InsertBST(T,a);
InsertBST(T,a);
DeleteBST(T,1);
system("pause");
return 0;
}