数据结构 树型结构
作业内容:二叉树
作业要求1:
编写建立二叉树的动态(或者静态)二叉链表存储结构(左右链表示)的程序,并以适当的形式显示和保存二叉树 。
结点设计:
typedef struct BinaryTree{
type data;
int leve;
struct BinaryTree* Lchild;
struct BinaryTree* Rchild;
}BT;
BT* Node(type x, BT* L,BT* R)//创建节点
{
BT* p=(BT*)malloc(sizeof(BT));
if(p==NULL)
{
printf("fail!");
}
p->data=x;
p->Lchild=L;
p->Rchild=R;
return p;
}
使用文件读入创建二叉树操作:
BT* createBT(FILE* fp)//根据文件tree.txt创建二叉树
{
BT*p;
int x;
//printf("Please enter the data( 0 for no data ): ");
fscanf(fp," %d",&x);
if(x==0)
{
return NULL;
}
else
{
p=(BT*)malloc(sizeof(BT));
p->data=x;
//printf("The left tree's data:\n");
p->Lchild=createBT(fp);
//printf("The right tree's data:\n");
p->Rchild=createBT(fp);
}
return p;
}
使用上述方式创造了以下三种二叉树(后用T1,T2,T3来表示):略
作业要求2:
采用二叉树的上述二叉链表存储结构,编写程序实现二叉树的先序、中序和后序遍历的递归和非递归算法以及层序遍历算法,并以适当的形式显示和保存二叉树及其相应的遍历序列 。
void PreOrder(BT* T)//递归的方式完成先序遍历二叉树
{
if(!IsEmpty(T))
{
visit(T);
PreOrder(T->Lchild);
PreOrder(T->Rchild);
}
else
return;
}
void MidOrder(BT* T)//递归的方式完成中序遍历二叉树
{
if(!IsEmpty(T))
{
MidOrder(T->Lchild);
visit(T);
MidOrder(T->Rchild);
}
else
return;
}
void AftOrder(BT* T)//递归的方式完成后序遍历二叉树
{
if(!IsEmpty(T))
{
AftOrder(T->Lchild);
AftOrder(T->Rchild);
visit(T);
}
else
return;
}
void PreOrder_X(BT*T)//循环的方式完成先序遍历二叉树
{
ST S;
S.top=-1;
BT* p=T;
while(1)
{
if(p->Lchild!=NULL)
{
printf("%d ",p->data);
push(p,&S);
p=p->Lchild;
}
else
{
if(p->Rchild!=NULL)
{
printf("%d ",p->data);
p=p->Rchild;
}
else if(p->Rchild==NULL)
{
printf("%d ",p->data);
if(S.top!=-1)
{
p=pop(&S);
while(p->Rchild==NULL)
p=pop(&S);
p=p->Rchild;
}
else break;
}
}
}
}
void MidOrder_X(BT*T)//循环的方式完成中序遍历二叉树
{
ST S;
S.top=-1;
BT* p=T;
while(1)
{
if(p->Lchild!=NULL)
{
push(p,&S);
p=p->Lchild;
}
else
{
if(p->Rchild!=NULL)
{
printf("%d ",p->data);
p=p->Rchild;
}
else if(p->Rchild==NULL)
{
printf("%d ",p->data);
if(S.top!=-1)
{
p=pop(&S);
printf("%d ",p->data);
while(p->Rchild==NULL)
{
p=pop(&S);
printf("%d ",p->data);
}
p=p->Rchild;
}
else break;
}
}
}
}
void AftOrder_X(BT*T)//循环的方式完成后序遍历二叉树
{
ST S;
int s[maxlength];
S.top=-1;
BT* p=T;
while(p!=NULL||S.top!=-1)
{
while(p!=NULL)
{
push(p,&S);
s[S.top]=1;
p=p->Lchild;
}
while(S.top!=-1&&s[S.top]==2)
{
p=pop(&S);
printf("%d ",p->data);
}
if(S.top!=-1)
{
s[S.top]=2;
p=pop(&S);
push(p,&S);
p=p->Rchild;
}
if(p==T&&S.top==-1)
break;
}
}
其中涉及到循环过程中使用栈结构,有关栈结构的部分如下:
typedef struct Stack{
int top;
BT* s[maxlength];
}ST;
void push(BT* T,ST* S)//压入栈中的元素
{
if(S->top>=maxlength)
{
return;
}
else
{
S->top++;
S->s[S->top]=T;
}
}
BT* pop(ST* S)//弹出栈内部的元素
{
if(S->top==-1)
{
return NULL;
}
else{
S->top--;
return S->s[S->top+1];
}
}
作业要求3:
设计并实现判断任意一棵二叉树是否为完全二叉树的算法。
int Judge(BT*T)//判断是否为二叉树
{
int head=0,tail=0;
BT* Q[maxlength];
if(T==NULL)return 0;
Q[tail++]=T;
T->leve=1;
BT* temp;
int hight=Hight(T);
int dev[maxlength];
while(head!=tail)
{
temp=Q[head++];
if(temp->Lchild!=NULL)Q[tail++]=temp->Lchild;
if(temp->Rchild!=NULL)Q[tail++]=temp->Rchild;
}
for(int i=0;i<=head-1;i++)
{
dev[i]=Dev(Q[i]);
if(i<=pow(2,hight-2)-2)
{
if(dev[i]!=2)
return 0;
}
if(dev[i]==1)
{
if(Q[i]->Lchild==NULL)
return 0;
}
}
return 1;
}
作业要求4:
设计并实现计算任意一棵二叉树的宽度的(递归或非递归)算法。二叉树的
宽度是指其各层结点数的最大值。
int level[maxlength]={0};//记录二叉树的宽度
int Wid=0;//表明二叉树的宽度
void Width(BT*T,int leve)//递归计算二叉树的宽度
{
if(T==NULL)
{
return ;
}
level[leve]++;
Wid=level[leve]>Wid?level[leve]:Wid;
Width(T->Lchild,leve+1);
Width(T->Rchild,leve+1);
}
int Width_X(BT*T)//循环计算二叉树的宽度
{
int head=0,tail=0;
BT* Q[maxlength];
if(T==NULL)return 0;
Q[tail++]=T;
T->leve=0;
BT* temp;
int* leve=(int*)malloc(sizeof(int)*Hight(T));
while(head!=tail)
{
temp=Q[head++];
if(temp->Lchild!=NULL)
{
Q[tail++]=temp->Lchild;
temp->Lchild->leve=temp->leve+1;
}
if(temp->Rchild!=NULL)
{
Q[tail++]=temp->Rchild;
temp->Rchild->leve=temp->leve+1;
}
}
for(int i=0;i<=head-1;i++)
{
leve[i]=0;
}
for(int i=0;i<=head-1;i++)
{
int j=Q[i]->leve;
leve[j]++;
}
return FindMax(leve,Hight(T));
}
程序测试
T1:
Please Enter your choice( 0 for exit ):1
先序递归遍历二叉树结果:4 3 2 1 1 2 1 1 3 2 1 1 2 1 1
先序循环遍历二叉树结果:4 3 2 1 1 2 1 1 3 2 1 1 2 1 1
Please Enter your choice( 0 for exit ):2
中序递归遍历二叉树结果:1 2 1 3 1 2 1 4 1 2 1 3 1 2 1
中序循环遍历二叉树结果:1 2 1 3 1 2 1 4 1 2 1 3 1 2 1
Please Enter your choice( 0 for exit ):3
后序递归遍历二叉树结果:1 1 2 1 1 2 3 1 1 2 1 1 2 3 4
后序循环遍历二叉树结果:1 1 2 1 1 2 3 1 1 2 1 1 2 3 4
Please Enter your choice( 0 for exit ):4
层序遍历二叉树结果:4 3 3 2 2 2 2 1 1 1 1 1 1 1 1
Please Enter your choice( 0 for exit ):5
判断二叉树是否为完全二叉树:
是
Please Enter your choice( 0 for exit ):6
递归计算二叉树宽度:8
Please Enter your choice( 0 for exit ):7
循环计算二叉树宽度:8
T2:
Please Enter your choice( 0 for exit ):1
先序递归遍历二叉树结果:4 3 2 1 2 1 1 3 2 1 2
先序循环遍历二叉树结果:4 3 2 1 2 1 1 3 2 1 2
Please Enter your choice( 0 for exit ):2
中序递归遍历二叉树结果:2 1 3 1 2 1 4 1 2 3 2
中序循环遍历二叉树结果:2 1 3 1 2 1 4 1 2 3 2
Please Enter your choice( 0 for exit ):3
后序递归遍历二叉树结果:1 2 1 1 2 3 1 2 2 3 4
后序循环遍历二叉树结果:1 2 1 1 2 3 1 2 2 3 4
Please Enter your choice( 0 for exit ):4
层序遍历二叉树结果:4 3 3 2 2 2 2 1 1 1 1
Please Enter your choice( 0 for exit ):5
判断二叉树是否为完全二叉树:
否
Please Enter your choice( 0 for exit ):6
递归计算二叉树宽度:4
Please Enter your choice( 0 for exit ):7
循环计算二叉树宽度:4
T3:
Please Enter your choice( 0 for exit ):1
先序递归遍历二叉树结果:4 3 2 1 1 2 1 1 3 2 1 2
先序循环遍历二叉树结果:4 3 2 1 1 2 1 1 3 2 1 2
Please Enter your choice( 0 for exit ):2
中序递归遍历二叉树结果:1 2 1 3 1 2 1 4 1 2 3 2
中序循环遍历二叉树结果:1 2 1 3 1 2 1 4 1 2 3 2
Please Enter your choice( 0 for exit ):3
后序递归遍历二叉树结果:1 1 2 1 1 2 3 1 2 2 3 4
后序循环遍历二叉树结果:1 1 2 1 1 2 3 1 2 2 3 4
Please Enter your choice( 0 for exit ):4
层序遍历二叉树结果:4 3 3 2 2 2 2 1 1 1 1 1
Please Enter your choice( 0 for exit ):5
判断二叉树是否为完全二叉树:
是
Please Enter your choice( 0 for exit ):6
递归计算二叉树宽度:5
Please Enter your choice( 0 for exit ):7
循环计算二叉树宽度:5