#include <stdio.h>
#include<stdlib.h>
#define Ok 1
#define Error 0
#define max 20
#define Status int
typedef struct Btree{
Btree *lchild;
Btree *rchild;
int data;
}Btree,*Bitree; //二叉排序树的结构体,和普通二叉树节点的结构一样
Btree *creattree(Bitree &b)//创建一个二叉树(普通的二叉树递归创建)
{
int ch1;
scanf("%d",&ch1);
if(ch1==0)
b=NULL;
else
{
b=(Btree*)malloc(sizeof(Btree));
if(!b) exit(1);
b->data=ch1;
printf("请输入%d的左节点",b->data);
b->lchild=creattree(b->lchild);
printf("请输入%d的右节点",b->data);
b->rchild=creattree(b->rchild);
}
return b;
}
bool EQ(int i,int j)
{
if(i==j)
return 1;
else
return 0;
}
bool LT(int i,int j)
{
if(i<j)
return 1;
else
return 0;
}
Status SearchBST(Bitree t,int key,Bitree f,Bitree &p)//二叉查找树入口
{
if(!t) {p=f; return false; } //如果是一颗空树的话直接返回0
else if(EQ(key,t->data)) {p=t; return true;}//如果找到对应的记录的话,把找到的节点赋给p,返回1
else if(LT(key,t->data)) return SearchBST(t->lchild,key,t,p);//如果在左子树的话递归到左子树查询
else return SearchBST(t->rchild,key,t,p);//如果在右子树的话递归到右子树查询
}
Status InsertBST(Bitree &t,int e)//向二叉排序树中插入节点
{
Bitree p,s;
if(!SearchBST(t,e,NULL,p))//先查找,如果没有这个记录再插入这个记录
{
s=(Bitree)malloc(sizeof(Btree));
s->data=e; s->lchild=s->rchild=NULL;//定义一个要插入的节点
if(!p) t=s; //如果是一个空树的话,让这个新节点作为整棵树的根节点
else if(LT(s->data,p->data)) p->lchild=s;//因为返回的p是整棵树的叶子节点,所以插入的节点只需比较与p的大小,
else p->rchild=s; //直接插入p的左孩子或是右孩子节点
return true ;
}
else return false;
}
Status Delete(Bitree &p)//在二叉排序树中删除节点
{
Bitree q,s;
//q=(Btree*)malloc(sizeof(Btree));
//s=(Btree*)malloc(sizeof(Btree));
if(!p->rchild)//如果要删除的这个节点没有右子树的话,直接让p变成p的lchild即可
{
q=p; p=p->lchild; free(q);
}
else if(!p->lchild) //如果要删除的这个节点没有左子树的话,直接让p变成p的rchild即可
{
q=p; p=p->rchild; free(q);
}
else//如果要删除的这个节点左右子树都存在的话
{
q=p; s=p->lchild;
while(s->rchild) {q=s;s=s->rchild;}//s是要删除的p节点的左孩子节点的右孩子节点里面最右面的一个,p是s的父节点
p->data=s->data; //把s里的数据赋值给P
q->rchild=s->lchild;//把最右面的左子树给倒数第二个的右子树
free(s);//把s删除
}
return Ok;
}
Status DeleteBST(Bitree &t,int key)//删除函数的入口
{
if(!t) return false;
else
{
if(EQ(key,t->data)) {return Delete(t);}//如果找到了就调用Delete函数
else if(LT(key,t->data)) return DeleteBST(t->lchild,key);//递归查找
else return DeleteBST(t->lchild,key);
}
}
Status Showtree(Bitree t)
{
if(t)
{
if(Showtree(t->lchild))
{
printf("%d\n",t->data);
if(Showtree(t->rchild))
return Ok;
}
}
else return Ok;
}
void main()
{
Bitree t;
int e;
printf("请输入树的根节点");
creattree(t);
printf("请输入您要查询的数字如果没有将插入图中");
scanf("%d",&e);
InsertBST(t,e);
printf("该树的中序序列为");
Showtree(t);
printf("请输入要删除的节点:");
scanf("%d",&e);
DeleteBST(t,e);
printf("该树的中序序列为:");
Showtree(t);
getchar();
getchar();
}
//算法分析:1.二叉排序树要求:(1)它的左子树不为空,那么所有节点的值均小于它很节点的值(2)它的右子树不为空,那么所有节点的值均大于它很节点的值
//(3)它的左右子树也符合
//2.在删除节点的算法中,处理方法有两种,一种是如上程序所写,将左子树最右边的一个节点值进行互换,删除那最右边的节点,还有一种就是将P节点直接删去
//将p的父节点和p的左孩子节点连接,再将P的有孩子节点直接连在p的左孩子节点的最右端,也就是s节点的右孩子节点
查找树-------二叉排序树
最新推荐文章于 2024-08-06 16:35:54 发布