1. 程式人生 > >二叉樹順序儲存的實現

二叉樹順序儲存的實現

在實現二叉樹的順序儲存的過程中,遇到了一些問題,現記錄如下:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100/*儲存空間初始分配量*/
#define MAX_TREE_SIZE 100/*定義樹的最大節點數*/

typedef int status;
typedef int elemtype;
typedef struct position {
    int level;
    int order;
} position;
typedef elemtype sqbitree[MAXSIZE];
elemtype null=0
;/*設0表示空*/ status visit(elemtype c) { printf("%d ",c); return OK; } status initbitree(sqbitree T) { int i=0; for(i=0; i<MAX_TREE_SIZE; i++) T[i]=null;/*初始化時將所有節點置為空*/ return OK; } /*建立二叉樹*/ status createbitree(sqbitree T) { int i=0; printf("請按層序輸入結點的值(整型),0表示空結點,輸999結束。結點數≤%d:\n"
,MAX_TREE_SIZE); while(i<10) { T[i]=i+1; /*T[(i+1)/2-1]是T[i]的雙親節點*/ if(i&&!T[(i+1)/2-1]&&T[i]) { printf("產生了沒有雙親節點的新節點\n"); return ERROR; } i++; } /*其餘節點置空*/ while(i<MAX_TREE_SIZE) { T[i]=null; i++; } return
OK; } /*判斷二叉樹為空*/ status emptybitree(sqbitree T) { if(!T[0]) return TRUE; else return FALSE; } /*求二叉樹深度*/ status depthbitree(sqbitree T) { int i,j=-1; /*從最後一個節點開始,找到第一個不為空的節點*/ for(i=MAX_TREE_SIZE-1; i>=0; i--) if(T[i]) break; i++; do { j++; } while(i>=pow(2,j)); return j; } /*返回二叉樹的根節點*/ status root(sqbitree T,elemtype *e) { if(emptybitree(T)) { printf("二叉樹為空\n"); return ERROR; } else { *e=T[0]; return OK; } } /*給二叉樹中第e層序對節點賦新值value*/ status refresh(sqbitree T,position e,elemtype value) { /*將e轉換成陣列下標,這個公式畫出示意圖很容易就能理解*/ int i=(int)(pow(2,e.level-1)+e.order-2); /*情況一:給葉子賦空但雙親為空,返回ERROR*/ if(!value&&!T[(i+1)/2-1]) return ERROR; /*情況二:給雙親賦空但葉子不為空,返回ERROR*/ if(!value&&T[i*2+1]||T[i*2+2]) return ERROR; T[i]=value; return OK; } /*返回一個節點的左孩子*/ elemtype leftchild(sqbitree T,elemtype e){ int i=0; if(!T[0]) return ERROR; for(i=0;i<MAX_TREE_SIZE;i++){ if(T[i]==e) return T[i*2+1]; } return ERROR; } /*返回一個節點的右孩子*/ elemtype rightchild(sqbitree T,elemtype e) { int i=0; if(!T[0]) { printf("空樹\n"); return null; } for(i=0; i<MAX_TREE_SIZE; i++) { if(T[i]==e) return T[i*2+2]; } return ERROR;/*沒找到*/ } /*返回一個節點的左兄弟,若e是T的左孩子或無左兄弟,則返回"空"*/ elemtype leftslibing(sqbitree T,elemtype e) { int i=0; if(!T[0]) { printf("空樹\n"); return null; } for(i=0; i<MAX_TREE_SIZE; i++) if(T[i]==e&&i%2==0)/*i為偶數,*則為右子孫,減一即可得到左兄弟*//*此外,這個地方寫i%2==0h和!i%2的結果不一樣,正在思考原因*/ return T[i-1]; return null; } /*回一個節點的右兄弟,若e是T的左孩子或無左兄弟,則返回"空"*/ elemtype rightslibing(sqbitree T,elemtype e) { int i=0; if(!T[0]) { printf("空樹\n"); return null; } for(i=0; i<MAX_TREE_SIZE; i++) { if(T[i]==e&&i%2)/*i為奇數,*則為左子孫,減一即可得到右兄弟*/ return T[i+1]; } return null; } /*返回雙親*/ elemtype parent(sqbitree T,elemtype e){ int i=0; for(i=0;i<MAX_TREE_SIZE;i++){ if(T[i]==e) return T[(i+1)/2-1]; } } /*遍歷二叉樹*/ /*前序遍歷*/ status preorder(sqbitree T,int i){ visit(T[i]);/*先訪問根節點,再遞迴訪問左子樹和右子樹*/ if(T[2*i+1]) preorder(T,2*i+1); if(T[2*i+2]) preorder(T,2*i+2); } status pretraverse(sqbitree T){ if(emptybitree(T)) return ERROR; else{ preorder(T,0);/*從0開始遞迴*/ printf("\n"); } return OK; } /*中序遍歷二叉樹*/ void InTraverse(sqbitree T,int e) { if(T[2*e+1]!=null) /* 左子樹不空 */ InTraverse(T,2*e+1); visit(T[e]); if(T[2*e+2]!=null) /* 右子樹不空 */ InTraverse(T,2*e+2); } status InOrderTraverse(sqbitree T) { if(!emptybitree(T)) /* 樹不空 */ InTraverse(T,0); printf("\n"); return OK; } /*後序遍歷二叉樹*/ status lastorder(sqbitree T,int i){ if(T[2*i+1]) lastorder(T,2*i+1); if(T[2*i+2]) lastorder(T,2*i+2); visit(T[i]); } status lasttraverse(sqbitree T){ if(emptybitree(T)) return ERROR; else{ lastorder(T,0); } printf("\n"); } int main(void) { status i; position p; elemtype e; sqbitree T; initbitree(T); createbitree(T); printf("建立二叉樹後,樹空否?%d(1:是 0:否) 樹的深度=%d\n",emptybitree(T),depthbitree(T)); printf("對二叉樹做前序遍歷:"); pretraverse(T); printf("對二叉樹做中序遍歷:"); InOrderTraverse(T); printf("對二叉樹做後序遍歷:"); lasttraverse(T); e=50; printf("修改層序為3,本層序號為2的節點的值,輸入新值為%d\n",e); p.level=3; p.order=2; refresh(T,p,50); printf("對二叉樹做前序遍歷:"); pretraverse(T); printf("節點50的雙親為%d,左右孩子分別為%d %d,左右兄弟為%d %d\n",parent(T,e),leftchild(T,e),rightchild(T,e),leftslibing(T,e),rightslibing(T,e)); initbitree(T); printf("清空二叉樹後,樹空否?%d(1:是 0:否) 樹的深度=%d\n",emptybitree(T),depthbitree(T)); root(T,&e); }