一、順序存儲結構
二叉樹的順序存儲結構一般只適用於完全二叉樹,其存儲形式用一組地址連續的存儲單元按照完全二叉樹的每個結點編號的順序存放結點的內容。因此,必須確定好樹中各數據元素的存放次序,使得各數據元素在這個存放次序中的相互位置能反映出數據元素之間的邏輯關系。
樹中每個結點的編號過程為:首先把樹根節點的編號定為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 }
運行結果:
最近在學數據結構,歡迎指正交流!!