二叉樹的陣列儲存及運算
阿新 • • 發佈:2019-02-03
二叉樹的陣列儲存
當用陣列儲存完全二叉樹時可以用節點的編號作為陣列下標
當用陣列儲存非完全二叉樹時也可以用節點的編號作為陣列下標,但是要補全節點序列.(用虛擬節點)
2017/8/30 更新
父子節點的位置運算:
陣列0下標不使用
父節點i的左子節點在位置(2*i);
父節點i的右子節點在位置(2*i+1);
子節點i的父節點在位置(i/2);
完整程式碼如下:
//this is tree node size
#define SIZE 20
//求深度
//完全二叉樹的最大節點數量s = (2^n)-1,n = 樹的高度
//對於一個數組結構的tree,要先求tree的深度n,求最大指數2^n-1=size = 2^n = size+1 。所以 n = log2 (size+1)。n向上取整
int getHeight2(int size){
return (int)ceil(log10((double)size+1)/log10(2.0));
}
//求左孩子
int *getLchild(int arr[],int index){
if(index*2 > SIZE){
//printf("this node is not lift child");
return NULL;
}
return &arr[index*2];
}
//求右孩子
int *getRchild(int arr[],int index){
if (index*2+1 > SIZE){
// printf("this node is not right child");
return NULL;
}
return &arr[index*2+1];
}
//求雙親
int *getParent(int arr[],int index){
if(index < 2 || index > SIZE){
printf("this node is not parent");
return NULL;
}
return &arr[index/2 ];
}
//先序遍歷
void perorder2(int *arr, int len){
printf("%d ",arr[len]);
if(getLchild(arr,len) != NULL)
perorder2(arr,*getLchild(arr,len));
if(getRchild(arr,len) != NULL)
perorder2(arr,*getRchild(arr,len));
}
//列印空格
void printCH(int k){
char *ch = " ";
while(k){
printf("%s",ch);
k--;
}
}
//print tree
//列印tree,這樣有直觀的感受,按層列印
void printTerr(int arr[]){
int tall = getHeight2(SIZE);//樹的高度,層數
int count = 0,length = 1, i;//換行計數
int k;//元素間距
//k 的值用於控制tree node 間距,當從root節點向下列印時, k是遞減的,k的遞減規律是: n = (n+1) - 2^n ;(n 是當前層數,n-1表示上一層,root的層數n = 數的高度,n從葉子(最末端)向根節點計數.2^n == 1<<n)
k = (1 << (tall+1)) - 1;
k = k - (1 << tall);
for(i = 1; i <= SIZE; i++){
printCH(k);//列印空格方法
printf("%d",arr[i]);//列印元素,每個元素前後要列印空格.
printCH(k);
count++;
//判斷是否列印空格,調整層數
if(count == length){
printf("\n\n");
count = 0;
length *=2;
tall--;
k = k - (1 << tall);
}
}
printf("\n");
}
//test tree for array
void treeArrsTest(){
int treeArr[] = {NULL,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
//先把tree打印出來,這樣比較直觀一點
printTerr(treeArr);
printf("\n");
perorder2(treeArr, 1);
printf("\n");
printf(" node 5 left child is : %d\n",*getLchild(treeArr,5));
printf(" node 5 right child is 6 : %d\n",*getRchild(treeArr,5));
printf(" node 5 parent is : %d\n",*getParent(treeArr,5));
}