1. 程式人生 > >實驗四:樹和二叉樹的實驗一

實驗四:樹和二叉樹的實驗一

實驗內容:

自己確定一個二叉樹(樹結點型別、數目和結構自定)利用順序結構方法儲存,實現樹的構造。

原始碼:

#include <stdio.h>

# include<string.h>

# include<math.h>

#include<stdlib.h>

#define ClearBiTree InitBiTree  

typedef char TElemType;

TElemType Nil=' ';

#define MAXSIZE 100

typedef TElemType BiTree[MAXSIZE];

typedef struct

{

int level,

order;

}position;

typedef int QElemType;

#define MAXQSIZE 5

typedef struct

{

QElemType *base;  

int front;

int rear;

}SqQueue;

int InitBiTree(BiTree B)

{

int i;

for(i=0;i<MAXSIZE;i++)

B[i]=Nil;

return 1;

}

void DestroyBiTree()

{

}

int CreateBiTree(BiTree B)

{

int i = 0, l;

char s[MAXSIZE];

printf("請按層序輸入結點的值(字元),空格表示空結點,結點數≤%d:\n", MAXSIZE);

printf("例如:abcefgh\n");

gets(s);

l = strlen(s);

for(;i<l;i++)

{

B[i]=s[i];

if(i!=0 && B[(i+1)/2-1] == Nil && B[i] != Nil)

{

printf("出現無雙親的非根結點%c\n",B[i]);

exit(0);

}

}

for(i=l;i<MAXSIZE;i++)  

B[i]=Nil;

return 1;

}

int BiTreeEmpty(BiTree B)

{

if(B[0]==Nil)

return 1;

else

return 0;

}

int BiTreeDepth(BiTree B)

{

int i,j=-1;

for(i=MAXSIZE-1;i>=0;i--)  

if(B[i] != Nil)

break;

i++;  

do

j++;

while(i>=pow(2,j));

return j;

}

int Root(BiTree B,TElemType *e)

{

if(BiTreeEmpty(B))

return 0;

else

{

*e=B[0];

return 1;

}

}

TElemType Value(BiTree B,position e)

{

return B[((int)pow(2,e.level-1) - 1) + (e.order - 1)];

}

int Assign(BiTree B,position e,TElemType value)

{

int i = (int)pow(2,e.level-1) + e.order - 2;

if(value != Nil && B[(i+1)/2-1] == Nil)  

return 0;

else if(value == Nil && (B[i*2+1] != Nil || B[i*2+2] != Nil))

return 0;

B[i]=value;

return 1;

}

TElemType Parent(BiTree B,TElemType e)

{

int i;

if(B[0]==Nil)  

return Nil;

for(i=1;i<=MAXSIZE-1;i++)

if(B[i]==e)  

return B[(i+1)/2-1];

return Nil;

}

TElemType LeftChild(BiTree B,TElemType e)

{

int i;

if(B[0]==Nil)  

return Nil;

for(i=0;i<=MAXSIZE-1;i++)

if(B[i]==e)

return B[i*2+1];

return Nil;

}

TElemType RightChild(BiTree B,TElemType e)

{

int i;

if(B[0]==Nil)

return Nil;

for(i=0;i<=MAXSIZE-1;i++)

if(B[i]==e)

return B[i*2+2];

return Nil;

}

TElemType LeftSibling(BiTree B,TElemType e)

{

int i;

if(B[0]==Nil)

return Nil;

for(i=1;i<=MAXSIZE-1;i++)

if(B[i] == e && i%2 == 0)

return B[i-1];

return Nil;

}

 

TElemType RightSibling(BiTree B,TElemType e)

{

int i;

if(B[0]==Nil)

return Nil;

for(i=1;i<=MAXSIZE-1;i++)

if(B[i]==e&&i%2)

return B[i+1];

return Nil;

}

void Move(BiTree q,int j,BiTree B,int i)

{

if(q[2*j+1] != Nil)

Move(q,(2*j+1),B,(2*i+1));  

if(q[2*j+2] != Nil)

Move(q,(2*j+2),B,(2*i+2));

B[i]=q[j];

q[j]=Nil;

}

int InsertChild(BiTree B,TElemType p,int LR,BiTree c)

{

int j,k,i=0;

for(j=0;j<(int)pow(2,BiTreeDepth(B))-1;j++)  

if(B[j]==p)

break;

k=2*j+1+LR;

if(B[k] != Nil)

Move(B,k,B,2*k+2);  

Move(c,i,B,k);  

return 1;

}

int InitQueue(SqQueue *Q)

{

(*Q).base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));

if(!(*Q).base)

exit(0);

(*Q).front=(*Q).rear=0;

return 1;

}

int EnQueue(SqQueue *Q,QElemType e)

{

if((*Q).rear>=MAXQSIZE)

{

(*Q).base=(QElemType *)realloc((*Q).base,((*Q).rear+1)*sizeof(QElemType));

if(!(*Q).base)

return 0;

}

*((*Q).base+(*Q).rear)=e;

(*Q).rear++;

return 1;

}

int DeQueue(SqQueue *Q,QElemType *e)

{

if((*Q).front==(*Q).rear)  

return 0;

*e=(*Q).base[(*Q).front];

(*Q).front=(*Q).front+1;

return 1;

}

int DeleteChild(BiTree B,position p,int LR)

{

int i;

int k=1;

SqQueue q;

InitQueue(&q);  

i=(int)pow(2,p.level-1)+p.order-2;  

if(B[i]==Nil)

return 0;

i=i*2+1+LR;

while(k)

{

if(B[2*i+1]!=Nil)

EnQueue(&q,2*i+1);  

if(B[2*i+2]!=Nil)  

EnQueue(&q,2*i+2);  

B[i]=Nil;

k=DeQueue(&q,&i);

}

return 1;

}

int(*VisitFunc)(TElemType);

void PreTraverse(BiTree B,int e)

{

VisitFunc(B[e]);

if(B[2*e+1]!=Nil)

PreTraverse(B,2*e+1);

if(B[2*e+2]!=Nil)

PreTraverse(B,2*e+2);

}

int PreOrderTraverse(BiTree B,int(*Visit)(TElemType))

{

VisitFunc=Visit;

if(!BiTreeEmpty(B))

PreTraverse(B,0);

printf("\n");

return 1;

}

void InTraverse(BiTree B,int e)

{

if(B[2*e+1]!=Nil)

InTraverse(B,2*e+1);

VisitFunc(B[e]);

if(B[2*e+2]!=Nil)

InTraverse(B,2*e+2);

}

int InOrderTraverse(BiTree B,int(*Visit)(TElemType))

{

VisitFunc=Visit;

if(!BiTreeEmpty(B))

InTraverse(B,0);

printf("\n");

return 1;

}

void PostTraverse(BiTree B,int e)

{

if(B[2*e+1]!=Nil)

PostTraverse(B,2*e+1);

if(B[2*e+2]!=Nil)  

PostTraverse(B,2*e+2);

VisitFunc(B[e]);

}

int PostOrderTraverse(BiTree B,int(*Visit)(TElemType))

{

VisitFunc = Visit;

if(!BiTreeEmpty(B))  

PostTraverse(B,0);

printf("\n");

return 1;

}

void LevelOrderTraverse(BiTree B,int(*Visit)(TElemType))

{

int i=MAXSIZE-1,j;

while(B[i] == Nil)

i--;  

for(j=0;j<=i;j++)  

if(B[j] != Nil)

Visit(B[j]);

printf("\n");

}

void Print(BiTree B)

{

int j,k;

position p;

TElemType e;

for(j=1;j<=BiTreeDepth(B);j++)

{

printf("第%d層: ",j);

for(k=1; k <= pow(2,j-1);k++)

{

p.level=j;

p.order=k;

e=Value(B,p);

if(e!=Nil)

printf("%d:%c ",k,e);

}

printf("\n");

}

}

int visit(TElemType e)

{

printf("%c ",e);

return 0;

}

int main()

{

int i,j;

position p;

TElemType e;

BiTree B,s;

InitBiTree(B);

CreateBiTree(B);

printf("建立二叉樹後,樹空否?%d(1:是 0:否) 樹的深度=%d\n",

BiTreeEmpty(B),BiTreeDepth(B));

i=Root(B,&e);

if(i)

printf("二叉樹的根為:%c\n",e);

else

printf("樹空,無根\n");

printf("層序遍歷二叉樹:\n");

LevelOrderTraverse(B,visit);

printf("中序遍歷二叉樹:\n");

InOrderTraverse(B,visit);

printf("後序遍歷二叉樹:\n");

PostOrderTraverse(B,visit);

printf("請輸入待修改結點的層號 本層序號: ");

scanf("%d%d%*c",&p.level,&p.order);

e=Value(B,p);

printf("待修改結點的原值為%c請輸入新值: ",e);

scanf("%c%*c",&e);

Assign(B,p,e);

printf("先序遍歷二叉樹:\n");

PreOrderTraverse(B,visit);

printf("結點%c的雙親為%c,左右孩子分別為",e,Parent(B,e));

printf("%c,%c,左右兄弟分別為",LeftChild(B,e),RightChild(B,e));

printf("%c,%c\n",LeftSibling(B,e),RightSibling(B,e));

InitBiTree(s);

printf("建立右子樹為空的樹s:\n");

CreateBiTree(s);

printf("樹s插到樹B中,請輸入樹T中樹s的雙親結點 s為左(0)或右(1)子樹: ");

scanf("%c%d%*c",&e,&j);

InsertChild(B,e,j,s);

Print(B);

printf("刪除子樹,請輸入待刪除子樹根結點的層號 本層序號 左(0)或右(1)子樹: ");

scanf("%d%d%d%*c",&p.level,&p.order,&j);

DeleteChild(B,p,j);

Print(B);

ClearBiTree(B);

printf("清除二叉樹後,樹空否?%d(1:是 0:否) 樹的深度=%d\n",

BiTreeEmpty(B),BiTreeDepth(B));

i=Root(B,&e);

if(i)

printf("二叉樹的根為:%c\n",e);

else

printf("樹空,無根\n");

system("pause");

return 0;

}

程式結果: