二叉樹順序存儲的實現

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

#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); 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章