#include <stdio.h>
#include <malloc.h>
#include <ctype.h>
# define MAXSIZE 40 // 待排顺序表最大长度
int corect=0;
#define OK 1
#define ERROR 0
typedef int KeyType; // 关键字类型为整数类型
typedef int ElemType; // 数据类型为整数类型
//数据结构定义模块
typedef struct{ //记录类型
KeyType key; // 关键字域
ElemType data; // 其它属性域,存储要存储的数据
}RcdType,*TRcdType;
typedef struct{ //数据表
RcdType r[MAXSIZE]; //数组中r[0]空出
int length; //数据表长度
}Arglist,*TArglist;
typedef struct BiTNode{ // 结点结构
RcdType data; //结点存储数据为记录类型
struct BiTNode *lchild,*rchild; // 左右孩子指针
}BiTNode,*BiTree;
BiTree root,p,f,g;
//初始一个空二叉树
int createbitree(BiTree &T){
//初始化二叉树T为空
T=(BiTree)malloc(sizeof(BiTNode));
if(!T) {
printf("空间分配出错!\n");
return 0;
}
T=NULL;
return 1;
}//createbitree
//数据表生成及显示模块
TArglist create(TArglist &L){
//生成有n个数据元素的数据表,并返回数据表头指针
int i;
L->r[0].data=L->r[0].key=0;
printf("请输入数据表元素,格式为(关键字 数据)(注意:数据类型均为整型且各元素关键字需不同!):\n");
for(i=1;i<=L->length;i++){
scanf("%d %d",&L->r[i].key,&L->r[i].data);
}
return L;
}//create
int printarg(TArglist L){
//打印出所生成的数据表
int i;
for(i=1;i<=L->length;i++)printf("%d %d \n",L->r[i].key,L->r[i].data);
printf("\n");
return 1;
}//printarg
int scanarg(TArglist &L){
//数据表输入及打印函数
printf("请您输入要创建的数据表的长度(请输入3~%d的整数!):\n",MAXSIZE);
scanf("%d",&L->length);
if(!(L->length<=MAXSIZE&&L->length>=3)){
printf("输入非法!请重新输入!\n");
scanarg(L);
}
L=create(L);
printf("生成的数据表为(关键字 数据):\n");
printarg(L);
return 1;
}//scanarg
//自动生成二叉排序树
int compare(BiTree &q,TArglist L,int i){
//递归法建立二叉排序树
if(L->r[i].key==q->data.key){
printf("输入数据表中存在关键字相同的元素,请重新进行建树操作!\n");
corect=0;
return 0;
}
else if(L->r[i].key>q->data.key){ //若该结点关键字比r[i]大,且其右子树为空则创建其右子树为r[i];否则比较其右子树
if(q->rchild==0){
q->rchild=(BiTree)malloc(sizeof(BiTNode));
if(!q->rchild){
printf("程序运行出错!\n");
return ERROR;
}
else{
q->rchild->data=L->r[i];
q->rchild->lchild=NULL;
q->rchild->rchild=NULL;
}
}
else compare(q->rchild,L,i);
}
else if(L->r[i].key<q->data.key){ //若该结点关键字比r[i]小,且其左子树为空则创建其左子树为r[i];否则比较其左子树
if(q->lchild==0){
q->lchild=(BiTree)malloc(sizeof(BiTNode));
if(!q->lchild){
printf("程序运行出错!\n");
return 0;
}
else{
q->lchild->data=L->r[i];
q->lchild->lchild=NULL;
q->lchild->rchild=NULL;
}
}
else compare(q->lchild,L,i);
}
return 1;
}//compare
int creatBiTree(BiTree &root,TArglist L)
{ //创建二叉排序树
int i=1;
if (L->r[i].key){
root=(BiTree)malloc(sizeof(BiTNode));
root->data.key=L->r[i].key;
root->data.data=L->r[i].data;
root->lchild=root->rchild=NULL;
}
else
{printf("程序运行出错!\n");return ERROR;}
for(++i;i<=L->length;i++)compare(root,L,i);
if(corect)printf("建树操作已完成!\n");
return 1;
}//creatBiTree
//查找模块
int SearchBST(BiTree T,KeyType k,BiTree &f,BiTree &p){
//在根指针T所指二叉排序树中递归地查找其关键字等于k的数据元素,
//若查找成功,则返回指针p指向该数据元素的结点,并返回函数值为OK;
//否则表明查找不成功,返回指针p指向查找路径上访问的最后一个结点,
//并返回函数值为ERROR; 指针f指向当前访问的结点的双亲,其初始调用值为NULL。
if(!T){ // 二叉排序树不为空 查找不成功
p=f;
return 0;
}
else if(k==T->data.key){ // 查找成功
p=T;
g=f;
printf("查找到了关键字为%d的元素:\n 关键字为:%d 数据为:%d \n",p->data.key,p->data.key,p->data.data);
return OK;
}
else if(k<T->data.key) SearchBST(T->lchild,k,T,p);
// 在左子树中继续查找
else SearchBST(T->rchild,k,T,p); // 在右子树中继续查找
} // SearchBST
//二叉排序树的插入算法
int InsertBST(BiTree &T,TRcdType e,BiTree &f,BiTree &p){
//当二叉排序树中不存在关键字等e.key的数据元素时,插入元素值为e的结点,并返回TRUE;否则,不进行插入并提示和返回FALSE
BiTree s;
if(!SearchBST(T,e->key,f,p)){
s=(BiTree)malloc(sizeof(BiTNode)); //为新结点分配空间
s->data.data=e->data;
s->data.key=e->key;
s->lchild=s->rchild=NULL;
if(!p)T=s; //插入s为新的根结点
else if(e->key<p->data.key)
p->lchild=s; //插入*s为*p的左孩子
else p->rchild=s; //插入*s为*p的右孩子
printf("插入操作已完成!\n");
return OK; //插入成功
}
else {
printf("要插入的数据已存在,插入操作失败!\n");
return ERROR;
}
} // InsertBST
//二叉排序树的删除算法
int DeleteBST(BiTree &T,KeyType k){
//若二叉排序树T中存在其关键字等于k的数据元素,则删除该数据元素结点,并返回函数值TRUE,否则返回函数值FALSE
BiTree q;
createbitree(q);
if(!T||!SearchBST(T,k,f,p)){ // 不存在关键字等于kval的数据元素
printf("未找到要删除的元素。删除操作失败!\n");
return ERROR;
}
else if(g->lchild==p){
if(!p->rchild&&p->lchild){ //右子树为空树则只需重接其左子树
g->lchild=p->lchild;
q=p;
free(q);
return OK;
}
else if(p->rchild&&!p->lchild){//左子树为空只需重接其右子树
g->lchild=p->rchild;
q=p;
free(q);
return OK;
}
else if(p->rchild&&p->lchild){
q=p;
free(q);
return OK;
}
}
else {
if(!p->rchild&&p->lchild){ //右子树为空树则只需重接它的左子树
g->rchild=p->lchild;
q=p;
free(q);
return OK;
}
else if(p->rchild&&!p->lchild){ // 左子树为空树只需重接它的右子树
g->rchild=p->rchild;
q=p;
free(q);
return OK;
}
else if(p->rchild&&p->lchild){
q=p;
free(q);
return OK;
}
}
}//DeleteBST
int visit(BiTree &T){
//对数据元素操作的应用函数
printf("%d %d \n",T->data.key,T->data.data);
return OK;
}//visit
int preordertraverse(BiTree &t){ //先序遍历
if(t){
if(visit(t))
if(preordertraverse(t->lchild))
if(preordertraverse(t->rchild)) return OK;
return ERROR;
}
else return OK;
}//preordertraverse
int inordertraverse(BiTree &t){ //中序遍历
if(t){
if(inordertraverse(t->lchild))
if(visit(t))
if(inordertraverse(t->rchild)) return OK;
return ERROR;
}
else return OK;
}//inordertraverse
int postordertraverse(BiTree &t){ //后序遍历
if(t){
if(postordertraverse(t->lchild))
if(postordertraverse(t->rchild))
if(visit(t)) return OK;
return ERROR;
}
else return OK;
}//postordertraverse
int menuselect(){ //菜单选择程序
int n;
printf("*********************************************\n");
printf("* 欢迎进入二叉排序树相关操作演示系统! *\n");
printf("* *\n");
printf("* 您可进行的操作有: *\n");
printf("* 1.建树操作; *\n");
printf("* 2.查找操作; *\n");
printf("*3.二叉排序树的遍历(a.先序遍历;b.中序遍历;c.后序遍历);*\n");
printf("* 4.二叉树的插入操作; *\n");
printf("* 5.二叉树的删除操作; *\n");
printf("* 6.退出系统; *\n");
printf("* *\n");
printf("**************************************8******\n");
printf("请输入操作代码:\n");
scanf("%d",&n);
if(n<=6&&n>=1)return n;
else return ERROR;
}//menuselect
int main(){
//主程序显示操作界面 实现各功能调用
TArglist L; //数据声明
int i=0,k=0,n=0;
char q='a';
TRcdType r,s;
L=(TArglist)malloc(sizeof(Arglist)); //初始化数据表L
L->length=0;
for(i;i<=MAXSIZE;i++) L->r[i].key=L->r[i].data=0;
createbitree(root); //建空树root p f g
createbitree(p);
createbitree(f);
r=s=(TRcdType)malloc(sizeof(RcdType)); //初始化r s
if(!r||!s)printf("数据初始化出错!\n");
else r->data=r->key=s->data=s->key=0;
for(;n=6;){
switch(menuselect()){
case 1:
scanarg(L); //输入数据表
creatBiTree(root,L); //创建二叉排序树
printf("\n");
break;
case 2:
printf("请输入要查找的数据的关键字:\n");
scanf("%d",&k);
if(!SearchBST(root,k,f,p))printf("未找到指定的元素!\n"); //查找
printf("\n");
break;
case 3:
{
printf("请输入要进行的遍历类型代码(回到上一级菜单请输入‘e’!):\n");
scanf("%s",&q);
switch(q){
case 'a':
printf("则先序遍历二叉排序树的结果为(关键字 数据):\n");
preordertraverse(root);
printf("\n");
break;
case 'b':
printf("则中序遍历二叉排序树的结果为(关键字 数据):\n");
inordertraverse(root);
printf("\n");
break;
case 'c':
printf("则后序遍历二叉排序树的结果为(关键字 数据):\n");
postordertraverse(root);
printf("\n");
break;
case 'e':
break;
default:
printf("操作代码输入错误!请输入“a”“b”“c”中的一个代码。\n");
printf("\n");
break;
}
break;
}
case 4:
printf("请输入要插入的数据(关键字 数据):\n");
scanf("%d %d",&r->key,&r->data);
InsertBST(root,r,f,p); //插入二叉排序树中没有的元素
printf("\n");
break;
case 5:
printf("请输入要删除的数据(关键字 数据):\n");
scanf("%d %d",&s->key,&s->data); //删除二叉排序树中已有的指定元素
if(DeleteBST(root,s->key))printf("指定元素已删除!\n");
printf("\n");
break;
case 6:
printf("已成功退出系统!\n");
break;
default:
printf("操作代码输入错误!请重新输入!(请输入“1”“2”“3”“4”“5 ”“6””中的一个操作代码。)\n");
}
}
}
数据结构之排序二叉树操作
最新推荐文章于 2022-08-04 17:03:07 发布