一、程序如下
/*
项目名称:二叉树的顺序存储结构
编译环境:VC++ 2008
作者相关:。。。
最后修改:2019.10.13
学习目标:1.掌握二叉树顺序存储结构的基本操作
注意事项:1.测试所有功能是否正常
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_TREE_SIZE 100//二叉树最大结点数
#define OK 1
#define ERROR 0
#define FALSE 0
#define TRUE 1
#define ClearBiTree InitBiTree
typedef bool Status;
typedef int TElemType;
typedef TElemType SqBiTree[MAX_TREE_SIZE];//0号单元存储根节点
typedef struct
{
int level,order;//结点的层,本层序号(每层从1开始)
}Position;
TElemType Nil=0;//设整型以0为空
Status InitBiTree(SqBiTree T);
Status CreatBiTree(SqBiTree T);
Status BiTreeEmpty(SqBiTree T);
int BiTreeDepth(SqBiTree T);
Status Root(SqBiTree T,TElemType *e);
TElemType Value(SqBiTree T,Position e);
Status Assign(SqBiTree T,Position e,TElemType value);
TElemType Parent(SqBiTree T,TElemType e);
TElemType LeftChild(SqBiTree T,TElemType e);
TElemType RightChild(SqBiTree T,TElemType e);
TElemType LeftSibling(SqBiTree T,TElemType e);
TElemType RightSibling(SqBiTree T,TElemType e);
void PreTraverse(SqBiTree T,int e);
Status PreOrderTraverse(SqBiTree T);
void InTraverse(SqBiTree T,int e);
Status InOrderTraverse(SqBiTree T);
void PostTraverse(SqBiTree T,int e);
Status PostOrderTraverse(SqBiTree T);
void LevelOrderTraverse(SqBiTree T);
void Print(SqBiTree T);
Status visit(TElemType c);
int main()
{
Status i;
TElemType e;
SqBiTree T;
Position p;
InitBiTree(T);
CreatBiTree(T);
printf("建立二叉树后,树空否?%d(1:是 0:否)\n",BiTreeEmpty(T));
printf("树的深度为:%d\n",BiTreeDepth(T));
i=Root(T,&e);
if(i)
printf("二叉树的根为: %d\n",e);
else
printf("树空,无根\n");
printf("层序遍历二叉树:\n");
LevelOrderTraverse(T);
printf("前序遍历二叉树:\n");
PreOrderTraverse(T);
printf("中序遍历二叉树:\n");
InOrderTraverse(T);
printf("后序遍历二叉树:\n");
PostOrderTraverse(T);
printf("修改结点的层号3本层序号2\n");
p.level=3;
p.order=2;
e=Value(T,p);
printf("待修改结点的原值为%d,请输入新值:50\n",e);
e=50;
Assign(T,p,e);
printf("前序遍历二叉树:\n");
PreOrderTraverse(T);
printf("结点%d的双亲为%d,左右孩子分别为",e,Parent(T,e));
printf("%d,%d,左右兄弟分别为",LeftChild(T,e),RightChild(T,e));
printf("%d,%d\n",LeftSibling(T,e),RightSibling(T,e));
ClearBiTree(T);
ClearBiTree(T);
printf("清除二叉树后,树空否?%d(1:是 0:否)\n",BiTreeEmpty(T));
i=Root(T,&e);
if(i)
printf("二叉树的根为:%d\n",e);
else
printf("树空,无根\n");
return 0;
}
//建立一棵空树
Status InitBiTree(SqBiTree T)
{
for(int i=0;i<MAX_TREE_SIZE;i++)
T[i]=Nil;
return OK;
}
//按层次次序输入二叉树结点中的值,构造二叉树
Status CreatBiTree(SqBiTree T)
{
int i=0;
printf("下面建立值为1~10的二叉树:\n");
while(i<10)
{
T[i]=i+1;//给树赋值1-10
if(i!=0&&T[(i+1)/2-1]==Nil&&T[i]!=Nil)
{
printf("出现无双亲的非根节点%d\n",T[i]);
exit(ERROR);
}
i++;
}
return OK;
}
Status BiTreeEmpty(SqBiTree T)
{
if(T[0]==Nil)//根节点为空,则树空
return TRUE;
else
return FALSE;
}
/*
1.求树的深度
2.2^(k-1)<=depth<=2^k
*/
int BiTreeDepth(SqBiTree T)
{
if(BiTreeEmpty(T))
return 0;
int i,depth=1;
for(i=MAX_TREE_SIZE-1;i>=0;--i)//找到最后的结点
if(T[i]!=Nil)
break;
++i;//得到结点数
while(i>=powl(2,depth))//powl表示求2的depth次幂
{
++depth;
}
return depth;
}
//若T非空,则用e返回T的根
Status Root(SqBiTree T,TElemType *e)
{
if(BiTreeEmpty(T))
return ERROR;
else
{
*e=T[0];
return OK;
}
}
//若T存在,e是T中结点位置,返回该位置结点的值
/*
1.level层从1~n结点 2.对应的本层次序
2^(level-1) 1
2^(level-1)+1 2
2^(level-1)+2 3
2^(level-1)+3 4
......
2^(level-1)+n n+1
2.可见n+1-n==1,设本层次序为e.order,第level层结点为2^(level-1)+a
那么a=e.order-1
3.那么该结点位置为2^(level-1)+e.order-1,该结点对应的值为
T[2^(level-1)+e.order-2]
*/
TElemType Value(SqBiTree T,Position e)
{
if(BiTreeEmpty(T))
return ERROR;
else
return T[(int)powl(2,e.level-1)+e.order-2];
}
//T存在,给处于位置e的结点重新赋值
Status Assign(SqBiTree T,Position e,TElemType value)
{
int i=(int)powl(2,e.level-1)+e.order-2;
if(value!=Nil&&T[(i+1)/2-1]==Nil)//给结点赋非空值但双亲为空
return ERROR;//例如完全二叉树按层序:1,0,3,0,0,4,5,给T[3]赋值就出错
else if(value==Nil&&(T[i*2+1]!=Nil||T[i*2+2]!=Nil))//给双亲赋空值但有叶子不空
return ERROR;
T[i]=value;
return OK;
}
//T存在,e为非根结点,返回它的双亲
TElemType Parent(SqBiTree T,TElemType e)
{
if(BiTreeEmpty(T))
return ERROR;
for(int i=1;i<MAX_TREE_SIZE;++i)
if(T[i]==e)
return T[(i+1)/2-1];
return Nil;//没有找到e
}
//T存在,e是T中某结点,返回其左孩子,没有就返回空
TElemType LeftChild(SqBiTree T,TElemType e)
{
if(BiTreeEmpty(T))
return ERROR;
for(int i=0;i<MAX_TREE_SIZE;++i)
if(T[i]==e)
return T[2*i+1];
return Nil;
}
//T存在,e是T中某结点,返回其右孩子,没有就返回空
TElemType RightChild(SqBiTree T,TElemType e)
{
if(BiTreeEmpty(T))
return ERROR;
for(int i=0;i<MAX_TREE_SIZE;++i)
if(T[i]==e)
return T[2*i+2];
return Nil;
}
//T存在,e是T中某结点,返回e的左兄弟;若e是左孩子或无左兄弟返回空
TElemType LeftSibling(SqBiTree T,TElemType e)
{
if(BiTreeEmpty(T))
return ERROR;
for(int i=1;i<MAX_TREE_SIZE;++i)
if(T[i]==e&&i%2==0)//找的e并且序号为偶数(右孩子)
return T[i-1];
return Nil;
}
//T存在,e是T中某结点,返回e的右兄弟;若e是右孩子或无右兄弟返回空
TElemType RightSibling(SqBiTree T,TElemType e)
{
if(BiTreeEmpty(T))
return ERROR;
for(int i=1;i<MAX_TREE_SIZE;++i)
if(T[i]==e&&i%2==1)//找的e并且序号为奇数(左孩子)
return T[i+1];
return Nil;
}
//PreOrderTraverse()调用
/*
递归调用
1.确定函数功能:先序遍历树,即"根左右"
2.确定递归终止条件,遍历左/右孩子时,结点为空时停止
3.确定联系,假设3个结点:0,1,2,发现PreTraverse(T,0)就能先序遍历这3个结点
4.因为1,2是0的两个孩子,假设结点为e,那么它的两个孩子就是2*e+1和2*e+2
*/
void PreTraverse(SqBiTree T,int e)
{
visit(T[e]);
if(T[2*e+1]!=Nil)//递归结束条件,左子树不空
PreTraverse(T,2*e+1);
//注意:上面这个递归结束后,下面这个e仍从0开始
if(T[2*e+2]!=Nil)//递归结束条件,右子树不空
PreTraverse(T,2*e+2);
}
//T存在,先序遍历T
Status PreOrderTraverse(SqBiTree T)
{
if(BiTreeEmpty(T))
return ERROR;
PreTraverse(T,0);
printf("\n");
return OK;
}
//供InOrderTraverse调用
void InTraverse(SqBiTree T,int e)
{
if(T[2*e+1]!=Nil)//左子树不空
InTraverse(T,2*e+1);
visit(T[e]);
if(T[2*e+2]!=Nil)//右子树不空
InTraverse(T,2*e+2);
}
//T存在,中序遍历,"左根右"
Status InOrderTraverse(SqBiTree T)
{
if(BiTreeEmpty(T))
return ERROR;
InTraverse(T,0);
printf("\n");
return OK;
}
//供PostOrderTraverse()调用,同样采用0,1,2找规律
void PostTraverse(SqBiTree T,int e)
{
if(T[2*e+1]!=Nil)
PostTraverse(T,2*e+1);
if(T[2*e+2]!=Nil)
PostTraverse(T,2*e+2);
visit(T[e]);
}
//后序遍历,"左右根"
Status PostOrderTraverse(SqBiTree T)
{
if(!BiTreeEmpty(T))
PostTraverse(T,0);
printf("\n");
return OK;
}
//层序遍历二叉树
void LevelOrderTraverse(SqBiTree T)
{
int i=MAX_TREE_SIZE-1;
while(T[i]==Nil)
--i;//找到最后一个非空结点对应的下标值
for(int j=0;j<=i;j++)
if(T[j]!=Nil)
visit(T[j]);//只遍历非空的结点
printf("\n");
}
//逐层、按本层序号输出二叉树;结点数i<=2^k-1
void Print(SqBiTree T)
{
Position p;
TElemType e;
for(int depth=1;depth<=BiTreeDepth(T);depth++)
{
printf("在%d层: ",depth);
for(int NodeOrder=1;NodeOrder<=powl(2,depth-1);NodeOrder++)
{
p.level=depth;
p.order=NodeOrder;
e=Value(T,p);
if(e!=Nil)//只遍历非空结点
printf("%d:%d ",NodeOrder,e);
}
printf("\n");
}
}
//输出元素值
Status visit(TElemType c)
{
printf("%d ",c);
return OK;
}
二、结果
![](https://i-blog.csdnimg.cn/blog_migrate/e60308d6773b40a1875dbb51fa2d448d.png)