二叉排序树的建立、插入、删除和查找
给出一组关键值,建立相应的二叉排序树,完成:
⑴结点的删除操作。要求可以实现删除根结点、叶子结点以及其它任意结点的功能;
⑵插入一个新结点的操作;
⑶对给定的值在二叉排序树进行查找;
⑷随时显示操作的结果。
要代码,完整代码
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int key;
struct node *lchild,*rchild;
}BSTNode;
//二叉排序树插入操作递归算法
BSTNode *InsertBST1(BSTNode *T, int key)
{
BSTNode *p, *q = T;
//p为待插入的新结点
p = (BSTNode *)malloc(sizeof(BSTNode));
p->key = key;
p->lchild = p->rchild = NULL;
if(T == NULL) //原树为空
T = p; //新插入的结点为新的根
//原树非空时将新结点p作为q的左孩子或右孩子插入
else
{
if(key == q->key)
return T;
if(key < q->key)
{
if(q->lchild ==NULL)
q->lchild = p;
else
InsertBST1(q->lchild, key);
}
if(key > q->key)
{
if(q->rchild ==NULL)
q->rchild = p;
else
InsertBST1(q->rchild, key);
}
}
return T;
}
BSTNode *InsertBST2(BSTNode *T, int key)
{
BSTNode *f, *p = T;
//查找插入位置
while(p)
{
if(key == p->key)
return T;//无须插入
f = p;//记录访问的结点
if(key < p->key)
p = p->lchild;
else
p = p->rchild;
//若key<p->key,则在左子树中查找,否则在右子树中查找
}
//p为待插入的新结点
p = (BSTNode *)malloc(sizeof(BSTNode));
p->key = key;
p->lchild = p->rchild = NULL;
if(T == NULL) //原树为空
T = p; //新插入的结点为新的根
//原树非空时将新结点q作为p的左孩子或右孩子插入
else
{
if(key < f->key)
f->lchild = p;
else f->rchild = p;
}
return T;
}
//二叉排序树删除操作
void DelBST(BSTNode *T,int key)
{
BSTNode *p = T, *f, *q, *s;
while(p)
{
if(p->key == key) break; //找到关键字为key的结点
f=p;//记下关键字key节点的父节点
p=(key < p->key)? p->lchild : p->rchild;//分别在*p的左、右子树中查找
}
if(!p) return;//二叉排序树中无关键字为key的结点
if(p->lchild == NULL && p->rchild == NULL)//p无左子树无右子树
{
if(p == T) T = NULL;//删除的是根节点
else
if(p == f->lchild)
f->lchild = NULL;
else
f->rchild = NULL;
}
else if(p->lchild == NULL && p->rchild != NULL)//p无左子树有右子树
{
if(f->lchild == p)
f->lchild = p->rchild;
else
f->rchild = p->rchild;
}
else if(p->rchild == NULL && p->lchild != NULL)//p有左子树无右子树
{
if (f->lchild == p)
f->lchild = p->lchild;
else
f->rchild = p->lchild;
}
else if(p->lchild != NULL && p->rchild != NULL)//p既有左子树又有右子树
{
q = p;
s = p->lchild;//转左
while(s->rchild)
{//然后向右到尽头
q = s;
s = s->rchild;//s指向被删节点的“前驱”(中序前驱)
}
p->key = s->key;//以p的中序前趋结点s代替p(即把s的数据复制到p中)
if(q != p)
q->rchild = s->lchild;//重接q的右子树
else
q->lchild = s->lchild;//重接q的左子树。
}
}
//创建二叉排序树
BSTNode *CreateBST()
{
BSTNode *T = NULL; //初始时T为空树
int key;
printf("请输入一系列数,以0结尾:");
while(1)
{
scanf("%d", &key);//读入一关键字
if(key == 0)
break;//假设key=0是输入结束标志
else
T = InsertBST1(T, key); //使用递归算法,将key插入二叉排序树T,改为 T = InsertBST2(T, key);为非递归插入算法
}
return T; //返回建立的二叉排序树的根指针
}
//二叉排序树查找递归算法
int BSTsearch1(BSTNode *T, int data)
{
BSTNode *p = T;
if(!p)
return 0;
else if(p->key == data)
return 1;
else if(p->key > data)
return BSTsearch1(p->lchild, data);
else
return BSTsearch1(p->rchild, data);
}
//二叉排序树查找非递归算法
int BSTsearch2(BSTNode *T, int data)
{
BSTNode *p = T;
while(p)
{
if(p->key == data)
return 1;
p = (p->key > data)? p->lchild : p->rchild;
}
return 0;
}
//中序遍历得到的是一个有序的序列,实现了排序功能
void Inorder(BSTNode *T)
{
if(T)
{
Inorder(T->lchild);
printf("%d ",T->key);
Inorder(T->rchild);
}
}
int main()
{
BSTNode *T = NULL;
int data1,data2;
T = CreateBST();
printf("以上述数建立的二叉排序树,中序遍历的结果:");
Inorder(T);
printf("\n输入待搜索的数据data1=");
scanf("%d", &data1);
//递归算法查找
if(BSTsearch1(T, data1))
printf("%d存在\n");
else
printf("%d不存在\n");
printf("\n输入插入数据");
scanf("%d", &data1);
InsertBST1(T, data1);
Inorder(T);
printf("\n输入待删除的数据data2=");
scanf("%d", &data2);
DelBST(T,data2);
printf("删除后的二叉排序树,中序遍历的结果:");
Inorder(T);
return 0;
}
参考:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <malloc.h>
#define error 0
#define ok 1
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int CreateBiTree(BiTree &T)
{
char ch;
scanf("%c",&ch);
if(ch=='#')
T=NULL;
else
{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
exit(error);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return ok;
}
void PreOrderBiTree(BiTree T)
{
if(T)
{
printf("%c",T->data);
PreOrderBiTree(T->lchild);
PreOrderBiTree(T->rchild);
}
}
void InOrderBiTree(BiTree T)
{
if(T)
{
InOrderBiTree(T->lchild); //中序遍历左子树
printf("%c",T->data); //访问结点
InOrderBiTree(T->rchild); //中序遍历右子树
}
}
void PostOrderBiTree(BiTree T)
{
if(T)
{
PostOrderBiTree(T->lchild);
PostOrderBiTree(T->rchild);
printf("%c",T->data);
}
}
main()
{
int i;
BiTree T;
printf("\t请输入树的各元素:\n\t");
CreateBiTree(T);
do
{
printf(" /*****************************/\n");
printf("\t1键:先序输出; \n\t2键:中序输出;\n\t3键:后序输出!\n\t0键:退出程序!\n");
printf("\t请输入你的选择:\n\t");
scanf("%d",&i);
switch(i)
{
case 1:printf("\n\t你选择的是先序输出!! \n");
printf("\n\t输出结果为:\n");
printf("\t");
PreOrderBiTree(T);break;
case 2:printf("\n\t你选择的是中序输出!! \n");
printf("\n\t输出结果为:\n");
printf("\t");
InOrderBiTree(T);break;
case 3:printf("\n\t你选择的是后序输出!! \n");
printf("\n\t输出结果为:\n");
printf("\t");
PostOrderBiTree(T);break;
}
printf("\n");
}while(i!=0);
return 0;
}
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!