軟考:資料結構基礎——建立順序完全二叉樹
阿新 • • 發佈:2018-12-01
首先是關於樹,二叉樹,完全二叉樹的一些知識
一、樹 (一)、基本概念 1. 度:一個節點的子樹的個數 2. 葉子節點:度為零的節點 3. 內部節點:度不為零的節點 4. 節點的層次,從根開始為第一層,之後的每個孩子節點為第i層 二、二叉樹 (一)、基本性質 1.二叉樹的第i層 多有 2^(i-1) 個節點 2.高度為k的二叉樹最多有2^k - 1 個節點 3.對於任意的二叉樹 若其終端節點(葉子節點)為n0 度為2的節點個數為 n2 則有 n0 = n2 + 1 4.對於具有n個節點的完全二叉樹 深度為log(2)n 向下取整再加 1 三、完全二叉樹 完全二叉樹使用順序儲存將極大的節省空間 我們設節點的編號為i,節點的個數為n (1<= i <=n) 1. 若節點標號為 i = 0 則該節點為根節點;若 i>1 則該節點的雙親節點為i/2向下取整有,等價於雙親節點的編碼在1~n/2之間 2. 若 2*i <= n,則該節點的左孩子編號為2i,否則該節點沒有左孩子。 2. 若 2*i +1 <= n, 則該節點的右孩子編號為2*i+1,否則該節點沒有右孩子。 四、建立順序儲存結構的完全二叉樹1 . 我們分析 完全二叉樹的編號規則,對於編碼是1~n 的 方式很容易實現,但是在順序儲存中(陣列下標索引)是以0~n-1來編碼的。需要一些特殊的方法來實現。
2 . 對於第一個節點,它的編碼應該是0,那麼它的 左右孩子節點分別應該是 1,2 但是如果按照2*i ,2*i+1的計算方式則是0,1。
3 . 對於0開始的編碼,節點序號為i 他的左右子節點應該是 2*i+1, 2*i+2, 而它的雙親節點編碼應該是 1~ n/2-1。 4 . 對於判斷是否為左右孩子節點的公式嗎,因為我們從 1~n 的排序變為了 0~n-1 所以我們的判斷條件也變成了2*i+1<=n-1,2*i+2<=n-1。 圖解:
建立一個Struct
typedef struct BiTnode{ int data; struct BiTnode *lchild, *rchild; }BiTnode,*BiTree;我們 malloc 一片連續的大小為BiTnode*n的空間 然後使用陣列下標索引先將值賦予這些值 之後在將每個節點的左右孩子通過上面所得到的公式進行連線,
#include <stdio.h> #include <stdlib.h> typedef struct BiTnode{ int data; struct BiTnode *lchild, *rchild; }BiTnode,*BiTree; /*根據陣列生成完全二叉樹*/ void Init(int data[], BiTree *T,int n){ int i; /*分配一片連續的空間,我們可以通過訪問下標來訪問在這片空間*/ *T = (BiTree)malloc(sizeof(BiTnode)*n); for(i=0;i<n;i++){ /*給這片連續的空間賦值,將陣列的值存入,應為我們使用的順序儲存*/ (*T)[i].data = data[i]; (*T)[i].lchild = NULL; (*T)[i].rchild = NULL; } /*為雙親節點確定子節點 n/2 是雙親節點的個數(序號)限定*/ for(i=0;i<=(n/2)-1;i++){ if(2*i+2<=n){ (*T)[i].lchild = &((*T)[2*i+1]); } if(2*i+3<= n){ (*T)[i].rchild = &((*T)[2*i+2]); } } } int main(){ BiTree T; int data[] = {1,2,3,4,5,6}; Init(data,&T,6); return 0; }
通過記憶體檢視 我們確定了建立成功