#include <stdio.h>
#include <stdlib.h>
typedef struct Bnode{
//存储结点的父结点,子结点数目,自身(同时也是其序号)以及所在树的根结点
int father,son_num,self;
struct Bnode *Lson,*Rson;//左儿子和右儿子
} Bnode,*Bptr;//用于定义结构体变量和指针
//定义结构体数组用于存树
Bnode tree[10000];
//定义根结点为空,即树为空
Bptr root=NULL;
//定义一个数组用来存根结点序号
int roots[100];
void creat(){
int x, y, i;
i=0;
printf("建立二叉树\n请输入(x y↙):");
scanf("%d %d",&x,&y);
//进入循环
while(x!=0||y!=0){
//若x,y都不在树中
if((!tree[x].self)&&(!tree[y].self)){
tree[x].self=x;
tree[x].father=-1;//根结点没有父亲,赋-1
tree[x].son_num=1;
tree[x].Lson=&tree[y];
tree[x].Rson=NULL;
roots[i]=x;
i++;
tree[y].self=y;
tree[y].father=x;
tree[y].son_num=0;
tree[y].Lson=tree[y].Rson=NULL;
}
//若y已存在树中
else if(tree[y].self==y){
printf("输入错误,%d已存在!\n",y);
}
//若x已存在树中,y不在
else if((tree[x].self==x)&&(!tree[y].self)){
switch(tree[x].son_num){
case(0):{
tree[x].son_num=1;
tree[x].Lson=&tree[y];
tree[x].Rson=NULL;
tree[y].self=y;
tree[y].father=x;
tree[y].son_num=0;
tree[y].Lson=tree[y].Rson=NULL;
break;}
case(1):{
tree[x].son_num=2;
tree[x].Rson=&tree[y];
tree[y].self=y;
tree[y].father=x;
tree[y].son_num=0;
tree[y].Lson=tree[y].Rson=NULL;
break;}
case(2):{
printf("%d儿子已满!\n",x);
break;}
}
}
//输入下一组(x y)
printf("请输入(x y↙):");
scanf("%d %d",&x,&y);
}
if(x==0&&y==0){
printf("输入结束!\n");
}
}
//单棵树的先序遍历
void preorder_1(Bptr p){
if(p==NULL||p->self==0)
return;
printf("%d\t",p->self);
preorder_1(p->Lson);
preorder_1(p->Rson);
}
//先序遍历
void preorder(){
Bptr p;
int k,m;
m=0;
//若根集为空,不存在任何树,则k值为空(或0)
if(!roots[0]){
printf("空树!");
}
else
while(roots[m]){
k=roots[m];
p=&tree[k];//把第一棵树的根指针赋给p
preorder_1( p);
m++;
}
}
//单棵树的中序遍历
void inorder_1(Bptr p){
if(p==NULL||p->self==0)
return;
preorder_1(p->Lson);
printf("%d\t",p->self);
preorder_1(p->Rson);
}
//中序遍历
void inorder(){
Bptr p;
int k,m;
m=0;
//若根集为空,不存在任何树,则k值为空(或0)
if(!roots[0]){
printf("空树!");
}
else
while(roots[m]){
k=roots[m];
p=&tree[k];//把第一棵树的根指针赋给p
inorder_1( p);
m++;
}
}
//单棵树的后序遍历
void postorder_1(Bptr p){
if(p==NULL||p->self==0)
return;
preorder_1(p->Lson);
preorder_1(p->Rson);
printf("%d\t",p->self);
}
//后序遍历
void postorder(){
Bptr p;
int k,m;
m=0;
//若根集为空,不存在任何树,则k值为空(或0)
if(!roots[0]){
printf("空树!");
}
else
while(roots[m]){
k=roots[m];
p=&tree[k];//把第一棵树的根指针赋给p
postorder_1( p);
m++;
}
}
//插入操作
void insert(){
int m,n;
int j=0;
//输入插入关系
printf("\n请输入要插入的结点,例如在m后面插入n(m n↙),输入(0 0↙)结束:");
scanf("%d %d",&m,&n);
//进入循环
while(m!=0||n!=0){
//若m不在现有的序列中
if(tree[m].self!=m){
tree[m].self=m;
tree[m].father=-1;//根结点没有父亲,赋-1
tree[m].son_num=1;
tree[m].Lson=&tree[n];
tree[m].Rson=NULL;
//将m放入根序列
for(j=0;j<100;j++){
if(!roots[j]){
roots[j]=m;
break;
}
}
tree[n].self=n;
tree[n].father=m;
tree[n].son_num=0;
tree[n].Lson=tree[n].Rson=NULL;
}
else{
//若n已存在于现有序列
if(tree[n].self==n)
printf("\n %d已存在!\n",n);
else{
switch(tree[m].son_num){
//n具体插入位置与m已有的儿子数有关
case(0):{
tree[m].son_num=1;
tree[m].Lson=&tree[n];
tree[m].Rson=NULL;
tree[n].self=n;
tree[n].father=m;
tree[n].son_num=0;
tree[n].Lson=tree[n].Rson=NULL;
break;}
case(1):{
tree[m].son_num=2;
tree[m].Rson=&tree[n];
tree[n].self=n;
tree[n].father=m;
tree[n].son_num=0;
tree[n].Lson=tree[n].Rson=NULL;
break;}
case(2):{
printf("%d儿子已满!\n",m);
break;}
}
}
}
printf("请输入要插入的结点,例如在m后面插入n(m n↙),输入(0 0↙)结束:");
scanf("%d %d",&m,&n);
}
if(m==0&&n==0){
printf("插入结束!");
}
}
//删除,由于delete为库函数,故重新命名delete_1
void delete_1(){
int x;
int j=0;
//输入删除结点
printf("\n请输入要删除的结点(输入-1结束):");
scanf("%d ",&x);
//进入循环
while(x!=-1){
//若x为根结点(即父亲为-1):x结点的子树成为独立的树
if(tree[x].father==-1){
switch(tree[x].son_num){
//具体操作与其儿子数有关
case(0):
{
//将x结点置空
tree[x].son_num=0;
tree[x].self=0;
tree[x].Lson=tree[x].Rson=NULL;
//将x从根序列中删除
for(j=0;j<100;j++){
if(roots[j]==x){
roots[j]=roots[j+1];
break;
}
}
while(roots[++j]){
roots[j]=roots[j+1];
}
break;
}
case(1):
{
//将根序列中x的位置用其左儿子替代
for(j=0;j<100;j++){
if(roots[j]==x){
roots[j]=tree[x].Lson->self;
break;
}
}
//将x结点置空
tree[x].son_num=0;
tree[x].self=0;
tree[x].Lson=tree[x].Rson=NULL;
break;
}
case(2):{
//将根序列中x的位置用其左儿子替代
for(j=0;j<100;j++){
if(roots[j]==x){
roots[j]=tree[x].Lson->self;
break;
}
}
//将右儿子也放入根序列
for(j=0;j<100;j++){
if(!roots[j]){
roots[j]=tree[x].Rson->self;
break;
}
}
break;}
}
}
//否则x为一普通结点,删除x后其子树也为独立树
else{
switch(tree[x].son_num){
//具体操作与其儿子数有关
case(0):{
//将x结点置空
tree[x].son_num=0;
tree[x].self=0;
tree[x].father=-1;
tree[x].Lson=tree[x].Rson=NULL;
break;}
case(1):{
//将x的子树独立
for(j=0;j<100;j++){
if(!roots[j]){
roots[j]=tree[x].Lson->self;
break;
}
}
//将x结点置空
tree[x].son_num=0;
tree[x].self=0;
tree[x].father=-1;
tree[x].Lson=tree[x].Rson=NULL;
break;}
case(2):{
//将x的子树独立
for(j=0;j<100;j++){
if(!roots[j]){
roots[j]=tree[x].Lson->self;
roots[j+1]=tree[x].Rson->self;
break;
}
}
//将x结点置空
tree[x].son_num=0;
tree[x].self=0;
tree[x].father=-1;
tree[x].Lson=tree[x].Rson=NULL;
break;}
}
}
}
}
void main(){
int i=0;
//构建
creat();
//输出根结点目录
printf("\n森里中各树的根结点目录:");
while(roots[i]){
printf("%d \t ",roots[i]);
i++;
}
//三种遍历
printf("\n先序遍历:");
preorder();
printf("\n中序遍历:");
inorder();
printf("\n后序遍历:");
postorder();
printf("\n");
//插入
insert();
//三种遍历
printf("\n先序遍历:");
preorder();
printf("\n中序遍历:");
inorder();
printf("\n后序遍历:");
postorder();
printf("\n");
//删除
delete_1();
//三种遍历
printf("\n先序遍历:");
preorder();
printf("\n中序遍历:");
inorder();
printf("\n后序遍历:");
postorder();
printf("\n");
}
删除可能还存在部分问题,但是,暂时先这样吧。。。