【实验内容】
二叉排序树采用二叉链表存储。写一个算法,删除结点值是X的结点。要求删除该结点后,此树仍然是一棵二叉排序树,并且高度没有增长(注:可不考虑被删除的结点是根的情况)。
【实验源码】 :
#include<stdio.h>
#include<stdlib.h>
//二叉树的动态链表结构
typedef struct BITNode
{
int key;
struct BITNode *lchild,*rchild;
}BITNode,*BiTree;
//排序二叉树的查找
bool SearchBST (BiTree T, int key, BiTree f, BiTree *p )
{
//若查找成功,则指针 p 指向该数据元素结点,并返回 TRUE
//否则指针 p 指向查找路径上访问的最后一个结点,并返回 FALSE
//指针 f 指向 T 的双亲,其初始调用值为NULL。
if (T==NULL)
{
*p = f;
return false;
} // 查找不成功
else
if ( key ==T->key )
{
*p = T;
return true;
} // 查找成功
else
if ( key < T->key )
SearchBST (T->lchild, key, T, p ); // 在左子树中查找
else
SearchBST (T->rchild, key, T, p ); // 在右子树中查找
}
//排序二叉树的建立
void CreateTree(BiTree *T,int n)
{
//建立含有n个结点的排序二叉树
int i,index;
BiTree p,s;
printf("请输入排序二叉树的关键字序列:\n");
for(i=1;i<=n;i++)
{
scanf("%d",&index);
if(!SearchBST( *T,index, NULL, &p ))//查找失败
{
s=(BiTree)malloc(sizeof(BITNode));
s->key=index;
s->lchild=NULL;
s->rchild=NULL;
if(!p)
*T=s;
else
if(index<p->key)
p->lchild = s; // 插入 s 为左孩子
else p -> rchild= s; // 插入 s 为右孩子
}
}
}
//中序遍历排序二叉树
void VisitBitree(BiTree T)
{
if(T)
{
VisitBitree(T->lchild);//访问左孩子
printf("%d->",T->key); //访问根节点
VisitBitree(T->rchild);//访问右孩子
}
}
//排序二叉树结点的删除
void Delete(BiTree &p)
{
BiTree q,s;
if(!p->rchild)//右子树为空
{
q=p;
p=p->lchild;
free(q);
}
if(!p->lchild)//左子树为空
{
q=p;
p=p->rchild;
free(q);
}
else//左右字数均不为空
{
q=p;
s=p->lchild;
while(s->rchild)
{
q=s;
s=s->lchild;
}
p->key=s->key;
if(q!=p)
q->rchild=s->lchild;
else
q->lchild=s->lchild;
}
}
bool DeleteBST(BiTree &T, int X)
{
if(!T)
return false; //不存在关键字等于key的数据元素
else
{
if (X==T->key)
{
Delete(T); //查找成功
return true;
}
else
if (X<T->key)
return DeleteBST (T->lchild,X);
else
return DeleteBST (T->rchild,X);
}
}
void main ()
{
int n,X;
BiTree T=NULL;
printf("请输入排序树序列元素个数:\n");
scanf("%d",&n);
CreateTree(&T,n);
printf("排序树序列中跟访问序列:\n");
VisitBitree(T);
printf("\n");
printf("输入你要删除的元素:");
scanf("%d",&X);
if(DeleteBST(T, X))
{
printf("排序树修改后的序列中跟访问序列如下:\n");
VisitBitree(T);
printf("\n");
}
else
printf("删除失败!该元素不在序列中\n");
}