您的位置:首页 > 其它

二叉树的顺序存储结构

2014-09-02 21:23 495 查看
#ifndef TREE_H
#define MAX_TREE_SIZE 20 /* 二叉树的最大结点数 */

#define OK 1
#define ERROR -1
typedef int Status ;
typedef  char TElemType ;
typedef TElemType SqBiTree[MAX_TREE_SIZE]; /* 0号单元存储根结点 */

typedef struct
{
int level,order; /* 结点的层,本层序号(按满二叉树计算) */
}position;
/////////////////基本操作////////////////////////////

Status InitBiTree(SqBiTree T);
void DestroyBiTree();
Status CreateBiTree(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 Move(SqBiTree Q,int j,SqBiTree T,int i);
Status InsertChild(SqBiTree T,TElemType p,Status LR,SqBiTree c);
Status DeleteChild(SqBiTree T,position p,int LR);
void PreTraverse(SqBiTree T,int e);
Status PreOrderTraverse(SqBiTree T,Status(*Visit)(TElemType));
void InTraverse(SqBiTree T,int e);
Status InOrderTraverse(SqBiTree T,Status(*Visit)(TElemType));
void PostTraverse(SqBiTree T,int e);
Status PostOrderTraverse(SqBiTree T,Status(*Visit)(TElemType));
void LevelOrderTraverse(SqBiTree T,Status(*Visit)(TElemType));
void Print(SqBiTree T);
#endif


#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include "c6_1.h"

Status InitBiTree(SqBiTree T){
/*构造空二叉树T,因为T是固定数组,不会改变,故不需要&*/
int i ;
for(i=0;i<MAX_TREE_SIZE;i++)
T[i]=NULL;
return OK;
}
void DestoryBiTree(SqBiTree T){
/*由于SqBiTree 是定长的,无法销毁*/
}

Status CreateBiTree(SqBiTree T){
/*按层次次输入二叉树中结点的值,(字符型),构造顺序存储结构的二叉树T*/
int i =0;
int l;
char s[MAX_TREE_SIZE];
printf("请按层次输入二叉树节点的值(字符),空格表示空结点,结点数<%d:\n",MAX_TREE_SIZE);
gets(s);      /*输入字符串*/
l = strlen(s);/*求字符串的长度*/
for(;i<l;i++){/*将字符串赋值给T*/
T[i]=s[i];
if(i!=0&&T[(i+1)/2-1]==NULL&&T[i]!=NULL){
printf("出现无双亲的非根结点%c\n",T[i]);
exit(ERROR);
}
}
for(i=l;l<MAX_TREE_SIZE;l++)/*将空值赋给l以后的值*/
T[i]=NULL;
return OK ;
}
#define ClearBiTree InitBiTree /* 在顺序存储结构中,两函数完全一样 */

Status BiTreeEmpty(SqBiTree T){
/* 初始条件: 二叉树T存在 */
/* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */
if(T[0]==NULL)
return true;
else
return false;
}
int BiTreeDepth(SqBiTree T){
/* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */
int i,j=-1;
for(i=MAX_TREE_SIZE-1;i>=0;i--) /* 找到最后一个结点 */
if(T[i]!=NULL)
break;
i++; /* 为了便于计算 */
do
j++;
while(i>=pow(2,j));
return j;
}

Status Root(SqBiTree T,TElemType *e){
/* 初始条件: 二叉树T存在 */
/* 操作结果:  当T不空,用e返回T的根,返回OK;否则返回ERROR,e无定义 */
if(BiTreeEmpty(T))
return ERROR;
else{
*e=T[0];
return OK ;
}
}

TElemType Value(SqBiTree T,position e){
/* 初始条件: 二叉树T存在,e是T中某个结点(的位置) */
/* 操作结果: 返回处于位置e(层,本层序号)的结点的值 */
return T[(int)pow(2,e.level-1)+e.order-2];
}
Status Assign(SqBiTree T,position e,TElemType value){
/* 初始条件: 二叉树T存在,e是T中某个结点(的位置) */
/* 操作结果: 给处于位置e(层,本层序号)的结点赋新值value */

int i = (int)pow(2,e.level-1)+e.order-2;/*计算出要插入的位置*/
/*插入检查*/
if(value!=NULL&&T[int((i+1)/2)-1]==NULL){
printf("值不为空,但没有双亲结点\n");
return ERROR;
}
else if(value==NULL&&T[2*i+1]!=NULL&&T[2*i+2]!=NULL){
printf("双亲不为空,但孩子都不为空\n");
return ERROR;
}
T[i]= value;
return OK ;

}
TElemType Parent(SqBiTree T,TElemType e){
/* 初始条件: 二叉树T存在,e是T中某个结点 */
/* 操作结果: 若e是T的非根结点,则返回它的双亲,否则返回"空" */
int i;
if(T[0]==NULL)/*空树*/
return ERROR ;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e)
return T[(int)(i+1)/2-1];
}
return NULL;
}
TElemType LeftChild(SqBiTree T,TElemType e){
/*初始条件:二叉树T存在,e是T中的结点*/
/*操作结果:返回e的左孩子*/
int i ;
if(T[0]==NULL)/*空树*/
return ERROR;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e)
return T[2*i+1];
}
return NULL;
}
TElemType RightChild(SqBiTree T,TElemType e){
/*初始条件:二叉树T存在,e是T中的结点*/
/*操作结果:返回e的右孩子*/
int i ;
if(T[0]==NULL)/*空树*/
return ERROR;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e)
return T[2*i+2];
}
return NULL;
}
TElemType LeftSibling(SqBiTree T,TElemType e){
/* 初始条件: 二叉树T存在,e是T中某个结点 */
/* 操作结果: 返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" */
int i;
if(T[0]==NULL)
return ERROR;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e&&i%2==0)/*找到e且其序号为偶数(是右孩子)*/
return T[i-1];
}
return NULL;
}
TElemType RightSibling(SqBiTree T,TElemType e){
/*初始条件:二叉树T存在,e是T中的某个结点*/
/*操作结果:返回e的右兄弟,若e是T的右孩子或是无右兄弟,则返回空*/
int i ;
if(T[0]==NULL)
return NULL;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e&&i%2==1)/*找到e且其序号为偶数(是右孩子)*/
return T[i+1];
}
return NULL;
}
void Move(SqBiTree Q,int j,SqBiTree T,int i){
/* 把从Q的j结点开始的子树移为从T的i结点开始的子树 */
if(Q[2*j+1]!=NULL)   /*Q的左子树不为空*/
Move(Q,(2*j+1),T,(2*i+1));
if(Q[2*j+2]!=NULL)   /*Q的右子树不空*/
Move(Q,(2*j+2),T,(2*i+2));/*把Q的j结点的右子树移为T的i结点的右子树*/
T[i]=Q[j];
Q[j]=NULL;
}
Status InsertChild(SqBiTree T,TElemType p,Status LR,SqBiTree c){
/* 初始条件: 二叉树T存在,p是T中某个结点的值,LR为0或1,非空二叉树c与T */
/*           不相交且右子树为空 */
/* 操作结果: 根据LR为0或1,插入c为T中p结点的左或右子树。p结点的原有左或 */
/*           右子树则成为c的右子树 */
int i,k ;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==p&&T[i]!=NULL)
break;
}
k=2*i+1+LR;/*p的左孩子或是右孩子的位置*/
if(T[k]!=NULL) /* p原来的左或右孩子不空 */
Move(T,k,T,2*k+2); /* 把从T的k结点开始的子树移为从k结点的右子树开始的子树 */
Move(c,i,T,k); /* 把从c的i结点开始的子树移为从T的k结点开始的子树 */
return OK;

}
Status DeleteChild(SqBiTree T,position p,int LR){
/* 初始条件: 二叉树T存在,p指向T中某个结点,LR为1或0 */
/* 操作结果: 根据LR为1或0,删除T中p所指结点的左或右子树 */
return OK;
}
Status(*VisitFunc)(TElemType); /* 函数变量 */
void PreTraverse(SqBiTree T,int e){
/* PreOrderTraverse()调用 */
VisitFunc(T[e]);
if(T[2*e+1]!=NULL) /* 左子树不空 */
PreTraverse(T,2*e+1);
if(T[2*e+2]!=NULL) /* 右子树不空 */
PreTraverse(T,2*e+2);
}

Status PreOrderTraverse(SqBiTree T,Status(*Visit)(TElemType))
{ /* 初始条件: 二叉树存在,Visit是对结点操作的应用函数 */
/* 操作结果: 先序遍历T,对每个结点调用函数Visit一次且仅一次。 */
/*           一旦Visit()失败,则操作失败 */
VisitFunc=Visit;
if(!BiTreeEmpty(T)) /* 树不空 */
PreTraverse(T,0);
printf("\n");
return OK;
}

void InTraverse(SqBiTree T,int e)
{ /* InOrderTraverse()调用 */
if(T[2*e+1]!=NULL) /* 左子树不空 */
InTraverse(T,2*e+1);
VisitFunc(T[e]);
if(T[2*e+2]!=NULL) /* 右子树不空 */
InTraverse(T,2*e+2);
}

Status InOrderTraverse(SqBiTree T,Status(*Visit)(TElemType))
{ /* 初始条件: 二叉树存在,Visit是对结点操作的应用函数 */
/* 操作结果: 中序遍历T,对每个结点调用函数Visit一次且仅一次。 */
/*           一旦Visit()失败,则操作失败 */
VisitFunc=Visit;
if(!BiTreeEmpty(T)) /* 树不空 */
InTraverse(T,0);
printf("\n");
return OK;
}

void PostTraverse(SqBiTree T,int e)
{ /* PostOrderTraverse()调用 */
if(T[2*e+1]!=NULL) /* 左子树不空 */
PostTraverse(T,2*e+1);
if(T[2*e+2]!=NULL) /* 右子树不空 */
PostTraverse(T,2*e+2);
VisitFunc(T[e]);
}

Status PostOrderTraverse(SqBiTree T,Status(*Visit)(TElemType))
{ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 */
/* 操作结果: 后序遍历T,对每个结点调用函数Visit一次且仅一次。 */
/*           一旦Visit()失败,则操作失败 */
VisitFunc=Visit;
if(!BiTreeEmpty(T)) /* 树不空 */
PostTraverse(T,0);
printf("\n");
return OK;
}

void LevelOrderTraverse(SqBiTree T,Status(*Visit)(TElemType))
{ /* 层序遍历二叉树 ,相当于遍历数组*/
int i=MAX_TREE_SIZE-1,j;
while(T[i]==NULL)
i--; /* 找到最后一个非空结点的序号 */
for(j=0;j<=i;j++)  /* 从根结点起,按层序遍历二叉树 */
if(T[j]!=NULL)
Visit(T[j]); /* 只遍历非空的结点 */
printf("\n");
}

void Print(SqBiTree T)
{ /* 逐层、按本层序号输出二叉树 */
int j,k;
position p;
TElemType e;
for(j=1;j<=BiTreeDepth(T);j++)
{
printf("第%d层: ",j);
for(k=1;k<=pow(2,j-1);k++)
{
p.level=j;
p.order=k;
e=Value(T,p);
if(e!=NULL)
printf("%d:%c ",k,e);
}
printf("\n");
}
}

Status visit(TElemType e){
printf("%c ",e);
return OK;
}
void main(){
SqBiTree T;
InitBiTree(T);
//	if(BiTreeEmpty(T)){
//		printf("树为空\n");
//	}
CreateBiTree(T);
//	if(!BiTreeEmpty(T)){
//		printf("树不为空\n");
//	}
//	printf("%d\n",BiTreeDepth(T));
//	ClearBiTree(T);
//	if(BiTreeEmpty(T)){
//		printf("树为空\n");
//	}
//	TElemType e ;
//	Root(T,&e);
//	printf("根为: %c\n",e);
//	position p;
//	p.level=2;
//	p.order=1;
//	printf("%c\n",Value(T,p));
//	Assign(T,p, '7');
//	printf("%c\n",Value(T,p));

printf("4 is parent = %c\n",Parent(T,'4'));
printf("5 is leftchild=%c\n",LeftChild(T,'5'));
printf("5 is RightChild=%c\n",RightChild(T,'5'));
printf("5 is LeftSibling=%c\n",LeftSibling(T,'5'));
printf("2 is RightSibling=%c\n",RightSibling(T,'2'));

Print(T);

printf("层序遍历二叉树:\n");
LevelOrderTraverse(T,visit);
printf("中序遍历二叉树:\n");
InOrderTraverse(T,visit);
printf("后序遍历二叉树:\n");
PostOrderTraverse(T,visit);
}

总结:

用一组连续的存储单元依次自上而下,自左向右存储完全二叉树的节点元素。将完全二叉树中的第i个结点存储在一维数组中的第i-1的分量中。

对于二叉树的顺序存储结构适合存储完全二叉树,否则会浪费大量的存储空间,最坏的情况是,一个深度为k且只有k个结点的单支书需要2^k-1的一维数组。

主要参考:严蔚敏数据结构

/article/5137388.html,对此作者表示感谢,给我很大的帮助
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: