#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");
}
刪除可能還存在部分問題,但是,暫時先這樣吧。。。