添加链接描述
这篇文章中介绍了二叉排序树的基本操作 如查找 插入 删除,具体概念上面的博客已经讲的很明白了 至于每行代码的作用 根据自身的理解, 在代码中加入了相关的标记
#include<stdio.h>
#include<stdlib.h>
//二叉树的二叉链表结点的结构定义
typedef struct BiTNode
{
int key; //结点的数据
struct BiTNode *lchild, *rchild;//左右孩子指针
} BiTNode, *BiTree;
//递归查找二叉排序树的查找是如何实现的'
//指针f是指向T的双亲 其初始调用值为NULL
//若查找成功 则指针p执行那个该数据元素的结点 并返回true
//否则指针p指向查找路径上访问的最后一个结点并返回false
int SearchBST(BiTree T,int key,BiTree f,BiTree &p )//查找
{
if(!T) {p=f;return 0;}//如果是空树 则返回0
else if (key==T->key) {p=T;return 1;}//如果key值就等于根结点的值 指针p指向key值对应的结点 所以这里P=T
else if(key<T->key) SearchBST(T->lchild,key,T,p);//遍历左孩子
else SearchBST(T->rchild,key,T,p); //遍历右孩子
}
//在二叉树中插入数据
int InsertBST(BiTree &T,int key)//插入
{
//这个函数是采用递归函数的思想 层层递归 最后新建一个结点 插入值
if(!T)
{//如果这颗树是空树,那么给这颗树分配空间 初始化二叉树
T=(BiTree)malloc(sizeof(BiTNode));
T->key=key;
T->lchild=(T)->rchild=NULL;
}
//如果要插入的值恰好等于根结点的值 那么就直接退出
if(key==T->key) return 0;
//左右递归
if(key>T->key) InsertBST(T->rchild,key);
else InsertBST(T->lchild,key);
}
//遍历方法 前面的文章中介绍过 这里就不再赘述
void InorderTraverse(BiTree T)//中序遍历
{
if(T)//判断这棵树是否为空
{ //按照LDR的顺序
InorderTraverse(T->lchild);
printf("%d ",T->key);
InorderTraverse(T->rchild);
}
}
void Delete(BiTree &p) //删除
{
BiTree q, s;
if(!p->lchild &&!p->rchild) //p为叶子节点
//如果这个结点没有左右孩子的话 直接将这个结点指针指向空 就代表删除了这个指针
p = NULL;
else if(!p->lchild) //左子树为空,重接右子树
{ //如果这棵树只有右子树
//那么删除这个结点后 将它的右子树放到原来的结点的位置
q=p; //将左子数赋值给临时指针q
p=p->rchild; //将右孩子放到原来的删除结点的位置
free(q); //释放q所指向的空间
}
else if(!p->rchild) //右子树为空,重接左子树
{ //左子树道理同右子shu
q=p;
p=p->lchild;
free(q);
}
else //左右子树均不为空 这种情况稍微复杂一点
//按照中中序排列 将要删除的结点的直接前驱放到被删除结点的位置
{
q=p; //现将q指向p所指向的空间
s=p->lchild; // 临时指针S指向p的左孩子
while(s->rchild)//一直遍历到s的最后一个右孩子
{
q=s; //将最后一个右孩子所指向的空间赋给p指针
//这里的意思就是将p指针左孩子的最后一个右孩子移位到原来p的指针
s=s->rchild;
}
p->key=s->key; //再将这个右孩子的数据域赋值给p
if(q!=p)//如果q指针与p指针不相等的时 将s的左孩子已到q结点的右孩子的位置
q->rchild=s->lchild;
else
//这里的else 是指q与p相等的情况 这个情况有点难理解
//就是指s没有经过70行的while循环 也就是s没有右孩子的情况
q->lchild=s->lchild;//就将s的左孩子重接到q的左孩子的位置
free(s);
}
}
int DeleteBST(BiTree &T, int key)//删除
{ //删除给定值的结点
if(!T) return 0;
else
{ //判断这个点是否是根结点
//下面是左右孩子遍历
if(key==T->key ) Delete(T);
else if(key<T->key) DeleteBST(T->lchild,key);
else DeleteBST(T->rchild,key);
}
}
int main()
{
int e,n;
BiTree T=NULL,f,p;
printf("输入长度:");
scanf("%d",&n);
printf("输入元素:");
while(n--)
{
scanf("%d",&e);
InsertBST(T, e);
}
printf("中序遍历:");
InorderTraverse(T);
printf("\n");
while(1)
{
printf("输入要查找元素:");
scanf("%d",&e);
if(SearchBST(T,e,f,p)) printf("找到了\n");
else printf("没找到\n");
printf("输入要插入元素:");
scanf("%d",&e);
InsertBST(T,e);
printf("中序遍历:");
InorderTraverse(T);
printf("\n");
printf("输入要删除元素:");
scanf("%d",&e);
DeleteBST(T,e);
printf("中序遍历:");
InorderTraverse(T);
printf("\n");
}
}
下面是运行的结果
输入长度:6
输入元素:3 0 9 4 7 5
中序遍历:0 3 4 5 7 9
输入要查找元素:0
找到了
输入要插入元素:6
中序遍历:0 3 4 5 6 7 9
输入要删除元素:7
中序遍历:0 3 4 5 6 9
输入要查找元素:9
找到了
输入要插入元素:9
中序遍历:0 3 4 5 6 9
输入要删除元素:9
中序遍历:0 3 4 5 6
输入要查找元素:9
没找到
输入要插入元素:^C