一、顺序存储结构
二叉树的顺序存储结构一般只适用于完全二叉树,其存储形式用一组地址连续的存储单元按照完全二叉树的每个结点编号的顺序存放结点的内容。因此,必须确定好树中各数据元素的存放次序,使得各数据元素在这个存放次序中的相互位置能反映出数据元素之间的逻辑关系。
树中每个结点的编号过程为:首先把树根节点的编号定为1,然后按照层次从上到下、每层从左到右的顺序,对每一结点进行编号。
若它是编号为i的双亲结点的左孩子结点,则它的编号应为2i;若它是右孩子结点,则它的编号应为(2i+1)
如图所示为一课完全二叉树及其顺序存储结构:
对于完全二叉树而言,其顺序存储结构是十分合适的,它能够充分利用存储空间。但对于一般的二叉树,特别是对于单分支较多的二叉树来说是很不合适的,因为可能只有少数存储单元被利用,大量的存储空间被无用的0或#占用(假设空结点或无效结点用0或#表示)
如图为一棵右斜树及其顺序存储结构:
由于顺序存储结构的这种缺陷,对于一般二叉树通常采用链式存储结构。
二、二叉树顺序存储结构的基本操作
(1)二叉树的初始化
void InitTree(SqBiTree &T){ int i; for(i=0;i<MAXTREESIZE;i++){ T[i]=0; } }
(2)创建二叉树
1 void CreateTree(SqBiTree &T,int a[],int n){ 2 int i=0; 3 while(i<n){ 4 i++; 5 T[i]=a[i-1]; 6 if(i!=1&&T[(i+1)/2]==0&&T[i]!=0){ 7 printf("出现无双亲的非根节点%d\n",T[i]); 8 exit(ERROR); 9 } 10 } 11 if(i>0)T[0]=i; 12 }
(3)遍历二叉树
1 void DispTree(SqBiTree T){ 2 int i=1; 3 printf("这棵完全二叉树为:\n"); 4 while(i<=T[0]){ 5 printf("%d ",T[i]); 6 if(T[i*2]!=0)printf("该结点的左孩子为%d ",T[i*2]); 7 else printf("该结点没有左孩子 "); 8 if(T[i*2+1]!=0)printf("该结点的右孩子为%d\n",T[i*2+1]); 9 else printf("该结点没有右孩子\n") ; 10 i++; 11 } 12 printf("\n"); 13 }
(4)获取双亲
1 int GetParent(SqBiTree &T,int num){ 2 int i; 3 if(T[0]=0)return 0; 4 for(i=1;i<=MAXTREESIZE;i++){ 5 if(T[i]==num)return T[i/2]; 6 } 7 }
(5)设置左右孩子的值
1 bool SetRightChild(SqBiTree &T,int i,int num){ 2 if((2*i+1)>=MAXTREESIZE)return false; 3 T[2*i+1]=num; 4 return true; 5 } 6 bool SetLeftChild(SqBiTree &T,int i,int num){ 7 if((2*i)>=MAXTREESIZE)return false; 8 T[2*i]=num; 9 return true; 10 }
整体代码:

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdbool.h> 4 #define ERROR 0 5 #define MAXTREESIZE 100 6 typedef int SqBiTree[MAXTREESIZE]; 7 void InitTree(SqBiTree &T){ 8 int i; 9 for(i=0;i<MAXTREESIZE;i++){ 10 T[i]=0; 11 } 12 } 13 void CreateTree(SqBiTree &T,int a[],int n){ 14 int i=0; 15 while(i<n){ 16 i++; 17 T[i]=a[i-1]; 18 if(i!=1&&T[(i+1)/2]==0&&T[i]!=0){ 19 printf("出现无双亲的非根节点%d\n",T[i]); 20 exit(ERROR); 21 } 22 } 23 if(i>0)T[0]=i; 24 } 25 void DispTree(SqBiTree T){ 26 int i=1; 27 printf("这棵完全二叉树为:\n"); 28 while(i<=T[0]){ 29 printf("%d ",T[i]); 30 if(T[i*2]!=0)printf("该结点的左孩子为%d ",T[i*2]); 31 else printf("该结点没有左孩子 "); 32 if(T[i*2+1]!=0)printf("该结点的右孩子为%d\n",T[i*2+1]); 33 else printf("该结点没有右孩子\n") ; 34 i++; 35 } 36 printf("\n"); 37 } 38 int GetParent(SqBiTree &T,int num){ 39 int i; 40 if(T[0]=0)return 0; 41 for(i=1;i<=MAXTREESIZE;i++){ 42 if(T[i]==num)return T[i/2]; 43 } 44 } 45 bool SetRightChild(SqBiTree &T,int i,int num){ 46 if((2*i+1)>=MAXTREESIZE)return false; 47 T[2*i+1]=num; 48 return true; 49 } 50 bool SetLeftChild(SqBiTree &T,int i,int num){ 51 if((2*i)>=MAXTREESIZE)return false; 52 T[2*i]=num; 53 return true; 54 } 55 int main(){ 56 SqBiTree T; 57 int num,e; 58 int a[10]={1,2,3,4,5,6,7,8,9,10}; 59 InitTree(T); 60 CreateTree(T,a,10); 61 DispTree(T); 62 printf("请输入你想查找的元素:"); 63 scanf("%d",&num); 64 e=GetParent(T,num); 65 printf("%d的双亲是:%d\n",num,e); 66 return 0; 67 }
运行结果:
最近在学数据结构,欢迎指正交流!!