數(shù)據(jù)結(jié)構(gòu)與算法15-二叉樹

1.概念

度:

結(jié)點(diǎn)擁有的子樹數(shù)目稱為結(jié)點(diǎn)的度纯出。

結(jié)點(diǎn)的層次:

從根開始定義起,根為第1層是趴,根的子結(jié)點(diǎn)為第2層涛舍,以此類推。

高度或深度:
  • 樹中結(jié)點(diǎn)的最大層次唆途。
  • 深度從上往下富雅。
  • 高度從下往上。
    以下不是標(biāo)準(zhǔn)定義肛搬,但對(duì)于我來說很容易記憶没佑。
滿二叉樹:

雙親結(jié)點(diǎn)都有2個(gè)兒子。

完全二叉樹:
  • 從根結(jié)點(diǎn)出發(fā)温赔,最深一層以上是滿二叉樹蛤奢。
  • 最后一層葉子結(jié)點(diǎn)是從左到右是連續(xù)的,不存在中間有空結(jié)點(diǎn)的情況。

2.實(shí)現(xiàn)

2.1 順序存儲(chǔ)
2.1.1 結(jié)構(gòu)定義
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 100 /* 存儲(chǔ)空間初始分配量 */
#define MAX_TREE_SIZE 100 /* 二叉樹的最大結(jié)點(diǎn)數(shù) */

typedef int Status;        /* Status是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼啤贩,如OK等 */
typedef int CElemType;      /* 樹結(jié)點(diǎn)的數(shù)據(jù)類型待秃,目前暫定為整型 */
typedef CElemType SqBiTree[MAX_TREE_SIZE]; /* 0號(hào)單元存儲(chǔ)根結(jié)點(diǎn)  */
CElemType Nil = 0;   /*設(shè)整型以0為空 或者以 INT_MAX(65535)*/

// 左兒子索引(雙親結(jié)點(diǎn)出發(fā))
#define LeftChild(x) (x)*2+1
// 雙親索引(左兒子反過來算)
// 右兒子多的1,除以2后為0痹屹,沒有影響
// 如果要記锥余,就記左兒子算法,雙親直接反推
#define Parent(x) ((x)-1)/2

// 查找用
typedef struct {
    int level; //結(jié)點(diǎn)層
    int order; //本層的序號(hào)(按照滿二叉樹給定序號(hào)規(guī)則)
} Position;
2.1.2 基礎(chǔ)操作
// 1.訪問
Status visit(CElemType c){
    printf("%d ", c);
    return OK;
}

// 2.構(gòu)造空二叉樹
Status InitBiTree(SqBiTree T) {
    memset(T, Nil, MAX_TREE_SIZE-1);
//    for (int i = 0; i < MAX_TREE_SIZE; i++) {
//        //將二叉樹初始化值置空
//        T[i] = Nil;
//    }
    return OK;
}

// 3.按層序次序輸入二叉樹中的結(jié)點(diǎn)值(字符型或整型)痢掠,構(gòu)造順序存儲(chǔ)的二叉樹T
Status CreateBiTree(SqBiTree T) {
    /*
            1       -->1
       2        3   -->2
     4    5   6   7 -->3
    8 9 10          -->4
    1 2 3 4 5 6 7 8 9 10 Nil Nil Nil
    */
    int i = 0;
    while (i < 10) {
        T[i] = i+1;
        printf("%d ",T[i]);
        //結(jié)點(diǎn)不為空,且無雙親結(jié)點(diǎn)
        if (i != 0 // 不是根結(jié)點(diǎn)需要判斷雙親
            && T[i] != Nil // 結(jié)點(diǎn)不為空嘲恍,如果雙親結(jié)點(diǎn)為空就有問題
            && T[Parent(i)] == Nil) { // 雙親結(jié)點(diǎn)為空
            printf("出現(xiàn)無雙親的非根結(jié)點(diǎn)%d\n",T[i]);
            T[i] = Nil;
            return ERROR;
            // 或者直接退出
//            exit(ERROR);
        }
        i++;
    }
    printf("\n");
    //將空賦值給T的后面的結(jié)點(diǎn)
    while (i < MAX_TREE_SIZE) {
        T[i] = Nil;
        i++;
    }
    return OK;
}

// 4.清空二叉樹
// 兩個(gè)函數(shù)完全一樣足画,沒必要寫2份,但是為了閱讀方便可以重命名
#define ClearBiTree InitBiTree

// 5.判斷二叉樹是否為空
Status BiTreeEmpty(SqBiTree T) {
    //根結(jié)點(diǎn)為空佃牛,則二叉樹為空
    if (T[0] == Nil)
        return TRUE;
    return FALSE;
}

// 6.獲取二叉樹的深度
int BiTreeDepth(SqBiTree T) {
    int i = MAX_TREE_SIZE - 1, j = 0;
    for (; i>=0 && T[i] == Nil; i--);// 最后一個(gè)葉子節(jié)點(diǎn)
    // 左斜樹序號(hào)  1 2 4 8 ...
    // 索引需要-1淹辞,0 1 3 7 ...,所以是powl(2, j)-1
    // j層的頭序號(hào)比最后一個(gè)葉子節(jié)點(diǎn)大時(shí)停止遍歷
    for (; powl(2, j)-1 <= i; j++);
    return j;
}

// 7.返回處于位置e(層,本層序號(hào))的結(jié)點(diǎn)值
CElemType Value(SqBiTree T, Position e){
    /*
     Position.level -> 結(jié)點(diǎn)層.表示第幾層;
     Position.order -> 本層的序號(hào)(按照滿二叉樹給定序號(hào)規(guī)則)
     */
    // 深度為層數(shù)-1
    int depth = e.level - 1;
    // 左斜樹序號(hào)  1 2 4 8 ...
    // 索引需要-1俘侠,0 1 3 7 ...象缀,所以是powl(2, depth)-1
    int levelStart = (int)pow(2, depth) - 1;
    // order從1開始而不是0,所以-1
    int idx = e.order - 1;
    return T[levelStart + idx];
}

// 8.獲取二叉樹跟結(jié)點(diǎn)的值
Status Root(SqBiTree T,CElemType *e){
    if (T[0] == Nil) return ERROR;
    *e = T[0];
    return OK;
}

// 9.給處于位置e的結(jié)點(diǎn)賦值
Status Assign(SqBiTree T, Position e, CElemType value) {
    // 深度為層數(shù)-1
    int depth = e.level - 1;
    // 左斜樹序號(hào)  1 2 4 8 ...
    // 索引需要-1爷速,0 1 3 7 ...央星,所以是powl(2, depth)-1
    int levelStart = (int)pow(2, depth) - 1;
    // order從1開始而不是0,所以-1
    int idx = e.order - 1;
    
    // 目標(biāo)位置
    int i = levelStart + idx;
    // 重點(diǎn)1:葉子結(jié)點(diǎn)的雙親為空
    if (value != Nil && T[Parent(i)] == Nil) return ERROR;
    // 重點(diǎn)2:給雙親賦空值但是有葉子結(jié)點(diǎn)
    if (value == Nil && (T[LeftChild(i)] != Nil || T[LeftChild(i)+1] != Nil)) return ERROR;
    // 成功賦值
    T[i] = value;
    return OK;
}

// 10.獲取e的雙親
CElemType ParentValue(SqBiTree T, CElemType e) {
    if (T[0] == Nil) return Nil; //空樹
    for (int i = 1 ; i < MAX_TREE_SIZE; i++) {
        if (T[i] == e) {
            return T[Parent(i)]; //找到e
        }
    }
    return Nil; //沒有找到
}

// 11.獲取某個(gè)結(jié)點(diǎn)的左孩子
CElemType LeftChildValue(SqBiTree T, CElemType e) {
    if (T[0] == Nil) return Nil; //空樹
    for (int i = 0 ; i < MAX_TREE_SIZE-1; i++) {
        if (T[i] == e) { //找到e
            return T[LeftChild(i)];
        }
    }
    return Nil; //沒有找到
}

// 12.獲取某個(gè)結(jié)點(diǎn)的右孩子
CElemType RightChild(SqBiTree T,CElemType e){
    if (T[0] == Nil) return Nil; //空樹
    for (int i = 0 ; i < MAX_TREE_SIZE-1; i++) {
        if (T[i] == e) { //找到e
            return T[LeftChild(i)+1];
        }
    }
    return Nil; //沒有找到
}

// 13.獲取結(jié)點(diǎn)的左兄弟惫东,e值必須是右孩子才有左兄弟
CElemType LeftSibling(SqBiTree T, CElemType e) {
    if (T[0] == Nil) return Nil; //空樹
    for (int i=1; i <= MAX_TREE_SIZE-1; i++) // 頭結(jié)點(diǎn)沒有左兄弟莉给,從1開始
        if (T[i]==e && i%2==0) return T[i-1]; // 找到e且其序號(hào)為偶數(shù)(是右孩子)
    return Nil; //沒有找到
}

// 14.獲取結(jié)點(diǎn)的右兄弟,e值必須是左孩子才有右兄弟
CElemType RightSibling(SqBiTree T, CElemType e) {
    if (T[0] == Nil) return Nil; //空樹
    for (int i=1; i <= MAX_TREE_SIZE-1; i++) // 頭結(jié)點(diǎn)沒有左兄弟廉沮,從1開始
        if (T[i]==e && i%2==1) return T[i+1]; // 找到e且其序號(hào)為奇數(shù)(是左孩子)
    return Nil; //沒有找到
}
2.1.3 遍歷
// 1.層序遍歷(存儲(chǔ)就是層序的)
void LevelOrderTraverse(SqBiTree T){
    int i = MAX_TREE_SIZE - 1;
    for (; i>=0 && T[i] == Nil; i--);// 最后一個(gè)葉子結(jié)點(diǎn)
    for (int j = 0; j <= i; j++) //從根結(jié)點(diǎn)起颓遏,按層序遍歷二叉樹
        if (T[j] != Nil) //只遍歷非空結(jié)點(diǎn)
            visit(T[j]);
    printf("\n");
}

// 2.前序遍歷二叉樹
void PreTraverse(SqBiTree T, int i){
    //打印結(jié)點(diǎn)數(shù)據(jù)
    visit(T[i]);
    //遍歷左子樹
    if (T[LeftChild(i)] != Nil) PreTraverse(T, LeftChild(i));
    //遍歷右子樹
    if (T[LeftChild(i)+1] != Nil) PreTraverse(T, LeftChild(i)+1);
}

Status PreOrderTraverse(SqBiTree T) {
    if (T[0] != Nil) //樹不為空
        PreTraverse(T, 0); // 遞歸遍歷
    printf("\n");
    return  OK;
}

// 3.中序遍歷二叉樹
void InTraverse(SqBiTree T, int i) {
    //遍歷左子樹
    if (T[LeftChild(i)] != Nil) InTraverse(T, LeftChild(i));
    //打印結(jié)點(diǎn)數(shù)據(jù)
    visit(T[i]);
    //遍歷右子樹
    if (T[LeftChild(i)+1] != Nil) InTraverse(T, LeftChild(i)+1);
}

Status InOrderTraverse(SqBiTree T) {
    if (T[0] != Nil) //樹不為空
        InTraverse(T, 0); // 遞歸遍歷
    printf("\n");
    return OK;
}

// 4.后序遍歷
void PostTraverse(SqBiTree T,int i) {
    //遍歷左子樹
    if (T[LeftChild(i)] != Nil) PostTraverse(T, LeftChild(i));
    //遍歷右子樹
    if (T[LeftChild(i)+1] != Nil) PostTraverse(T, LeftChild(i)+1);
    //打印結(jié)點(diǎn)數(shù)據(jù)
    visit(T[i]);
}

Status PostOrderTraverse(SqBiTree T) {
    if (T[0] != Nil) //樹不為空
        PostTraverse(T,0);
    printf("\n");
    return OK;
}
2.1.4 檢驗(yàn)
int main(int argc, const char * argv[]) {
    printf("二叉樹順序存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn)!\n");
    
    Status iStatus;
    Position p;
    CElemType e;
    SqBiTree T;
    /*
            1       -->1
       2        3   -->2
     4    5   6   7 -->3
    8 9 10          -->4
    1 2 3 4 5 6 7 8 9 10 Nil Nil Nil
    */
    InitBiTree(T);
    CreateBiTree(T);
    printf("建立二叉樹后,樹空否滞时?%d (1:是 0:否) \n",BiTreeEmpty(T));
    printf("樹的深度 = %d\n",BiTreeDepth(T));
    
    p.level = 3;
    p.order = 2;
    e = Value(T, p);
    printf("第%d層第%d個(gè)結(jié)點(diǎn)的值: %d\n",p.level,p.order,e);
    
    iStatus = Root(T, &e);
    if (iStatus) {
        printf("二叉樹的根為:%d\n",e);
    } else {
        printf("樹為空,無根!\n");
    }
  
    //向樹中3層第2個(gè)結(jié)點(diǎn)位置上結(jié)點(diǎn)賦值99
    e = 99;
    Assign(T, p, e);
    
    //獲取樹中3層第2個(gè)結(jié)點(diǎn)位置結(jié)點(diǎn)的值是多少:
    e = Value(T,p);
    printf("第%d層第%d個(gè)結(jié)點(diǎn)的值: %d\n",p.level,p.order,e);
    
    //找到e這個(gè)結(jié)點(diǎn)的雙親;
    printf("結(jié)點(diǎn)%d的雙親為: %d ", e, ParentValue(T, e));
    //找到e這個(gè)結(jié)點(diǎn)的左右孩子;
    printf("左右孩子分別為: %d, %d\n", LeftChildValue(T, e), RightChild(T, e));
    //找到e這個(gè)結(jié)點(diǎn)的左右兄弟;
    printf("結(jié)點(diǎn)%d的左右兄弟: %d, %d\n", e, LeftSibling(T, e), RightSibling(T, e));
    
    // 還原
    Assign(T, p, 5);
    
    // 開始遍歷
    printf("二叉樹T層序遍歷:");
    LevelOrderTraverse(T);
    printf("二叉樹T先序遍歷:");
    PreOrderTraverse(T);
    printf("二叉樹T中序遍歷:");
    InOrderTraverse(T);
    printf("二叉樹T后序遍歷:");
    PostOrderTraverse(T);
    return 0;
}
// 輸出
二叉樹順序存儲(chǔ)結(jié)構(gòu)實(shí)現(xiàn)!
1 2 3 4 5 6 7 8 9 10 
建立二叉樹后叁幢,樹空否?0 (1:是 0:否) 
樹的深度 = 4
第3層第2個(gè)結(jié)點(diǎn)的值: 5
二叉樹的根為:1
第3層第2個(gè)結(jié)點(diǎn)的值: 99
結(jié)點(diǎn)99的雙親為: 2 左右孩子分別為: 10, 0
結(jié)點(diǎn)99的左右兄弟: 4, 0
二叉樹T層序遍歷:1 2 3 4 5 6 7 8 9 10 
二叉樹T先序遍歷:1 2 4 8 9 5 10 3 6 7 
二叉樹T中序遍歷:8 4 9 2 10 5 1 6 3 7 
二叉樹T后序遍歷:8 9 4 10 5 2 6 7 3 1 
2.2 鏈?zhǔn)酱鎯?chǔ)
2.2.1 結(jié)構(gòu)定義
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

/* Status是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼坪稽,如OK等 */
typedef int Status;

// 數(shù)據(jù)結(jié)構(gòu)
typedef char CElemType;
CElemType Nil = '#'; /* 以#為空 */
typedef struct BiTNode { /* 結(jié)點(diǎn)結(jié)構(gòu) */
    CElemType data;        /* 結(jié)點(diǎn)數(shù)據(jù) */
    struct BiTNode *lchild, *rchild; /* 左右孩子指針 */
} BiTNode, *BiTree;

為了方便后續(xù)創(chuàng)建二叉樹:

// 全局變量
#define MAXSIZE 100 //存儲(chǔ)空間初始分配量
typedef char String[MAXSIZE]; /*  0號(hào)單元存放串的長度 */
String str;
Status StrAssign(String T, char *chars) {
    size_t length = strlen(chars);
    if (length > MAXSIZE) return ERROR;
    T[0] = length;
    for (int i = 1; i <= T[0]; i++)
        T[i] = *(chars+i-1);
    return OK;
}
2.2.2 基礎(chǔ)操作
// 1.打印數(shù)據(jù)
Status visit(CElemType e) {
    printf("%c ",e);
    return OK;
}

// 2.構(gòu)造空二叉樹T
Status InitBiTree(BiTree *T) {
    *T = NULL;
    return OK;
}

// 3.銷毀二叉樹
void DestroyBiTree(BiTree *T) {
    if (*T) {
        // 有左孩子
        if ((*T)->lchild)
            DestroyBiTree(&(*T)->lchild); // 銷毀左孩子子樹
        // 有右孩子
        if ((*T)->rchild)
            DestroyBiTree(&(*T)->rchild); // 銷毀右孩子子樹
        free(*T); // 釋放結(jié)點(diǎn)
        *T = NULL; // 指針賦空
    }
}

// 4.清空樹和銷毀代碼完全一樣
#define ClearBiTree DestroyBiTree

// 5.創(chuàng)建二叉樹
int createIndex = 1;
void CreateBiTree(BiTree *T) {
    CElemType ch = str[createIndex++]; // 獲取字符
    if (ch == Nil) { // 判斷當(dāng)前字符是否為空
        *T = NULL;
    } else {
        //創(chuàng)建新的結(jié)點(diǎn)
        *T = (BiTree)malloc(sizeof(BiTNode));
        //是否創(chuàng)建成功
        if (!*T) {
            exit(OVERFLOW);
        }
        (*T)->data = ch; // 生成根結(jié)點(diǎn)
        CreateBiTree(&(*T)->lchild); // 構(gòu)造左子樹
        CreateBiTree(&(*T)->rchild); // 構(gòu)造右子樹
    }
}

// 6.二叉樹T是否為空
Status BiTreeEmpty(BiTree T) {
    if (T)
        return FALSE;
    else
        return TRUE;
}

// 7.二叉樹T的深度
int BiTreeDepth(BiTree T) {
    if (!T) return 0;
    int i, j;
    i = T->lchild ? BiTreeDepth(T->lchild) : 0; // 計(jì)算左孩子的深度
    j = T->rchild ? BiTreeDepth(T->rchild) : 0; // 計(jì)算右孩子的深度
    return i > j ? i+1 : j+1; // 比較i和j
}

// 8.二叉樹T的根
CElemType Root(BiTree T) {
    if (BiTreeEmpty(T)) return Nil;
    return T->data;
}

// 9.返回p所指向的結(jié)點(diǎn)值
CElemType Value(BiTree p) {
    return p->data;
}

// 10.給p所指結(jié)點(diǎn)賦值為value
void Assign(BiTree p, CElemType value) {
    p->data = value;
}
2.2.3 遍歷
// 1.前序遞歸遍歷T
void PreOrderTraverse(BiTree T) {
    if (!T) return;
    printf("%c", T->data); // 顯示結(jié)點(diǎn)數(shù)據(jù)
    PreOrderTraverse(T->lchild); // 遍歷左子樹
    PreOrderTraverse(T->rchild); // 遍歷右子樹
}

// 2.中序遞歸遍歷T
void InOrderTraverse(BiTree T) {
    if (!T) return;
    InOrderTraverse(T->lchild); // 遍歷左子樹
    printf("%c", T->data); // 顯示結(jié)點(diǎn)數(shù)據(jù)
    InOrderTraverse(T->rchild); // 遍歷右子樹
}

// 3.后序遞歸遍歷T
void PostOrderTraverse(BiTree T) {
    if (!T) return;
    PostOrderTraverse(T->lchild); // 遍歷左子樹
    PostOrderTraverse(T->rchild); // 遍歷右子樹
    printf("%c", T->data); // 顯示結(jié)點(diǎn)數(shù)據(jù)
}
2.2.4 檢驗(yàn)
int main(int argc, const char * argv[]) {
    printf("二叉樹鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)實(shí)現(xiàn)!\n");
    
    BiTree T;
    CElemType e1;
    /*
                A
           B        C
         D   E     F   G
        H # # #   I # # J
       # K       # #   # #
        # #
     ABDH#K###E##CFI###G#J##
     */
    InitBiTree(&T);
    StrAssign(str,"ABDH#K###E##CFI###G#J##");
    CreateBiTree(&T);
    printf("二叉樹是否為空: %d (1:是 0:否)\n樹的深度: %d\n", BiTreeEmpty(T), BiTreeDepth(T));
    e1 = Root(T);
    printf("二叉樹的根為: %c\n",e1);
    printf("前序遍歷二叉樹:");
    PreOrderTraverse(T);
    printf("\n中序遍歷二叉樹:");
    InOrderTraverse(T);
    printf("\n后序遍歷二叉樹:");
    PostOrderTraverse(T);
    printf("\n");
    return 0;
}

// 輸出
二叉樹鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)實(shí)現(xiàn)!
二叉樹是否為空: 0 (1:是 0:否)
樹的深度: 5
二叉樹的根為: A
前序遍歷二叉樹:ABDHKECFIGJ
中序遍歷二叉樹:HKDBEAIFCGJ
后序遍歷二叉樹:KHDEBIFJGCA
2.2.5 非遞歸遍歷
// 1.前序循環(huán)遍歷T
void LoopPreOrderTraverse(BiTree T) {
    if (!T) return;
    // 這里偷懶知道樹高5
    int top = -1;
    BiTNode **stack = (BiTNode **)malloc(sizeof(BiTNode*) * 5);
    BiTNode *cur = T;
    while (cur || top > -1){
        while (cur) {
            stack[++top] = cur;
            printf("%c", cur->data); // 顯示結(jié)點(diǎn)數(shù)據(jù)
            cur = cur->lchild;
        }
        if (top > -1) {
            cur = stack[top];
            --top;
            cur = cur->rchild;
        }
    }
    free(stack);
}

// 2.前序循環(huán)遍歷T
void LoopInOrderTraverse(BiTree T) {
    if (!T) return;
    // 這里偷懶知道樹高5
    int top = -1;
    BiTNode **stack = (BiTNode **)malloc(sizeof(BiTNode*) * 5);
    BiTNode *cur = T;
    while (cur || top > -1){
        while (cur) {
            stack[++top] = cur;
            cur = cur->lchild;
        }
        if (top > -1) {
            cur = stack[top];
            printf("%c", cur->data); // 顯示結(jié)點(diǎn)數(shù)據(jù)
            --top;
            cur = cur->rchild;
        }
    }
    free(stack);
}

// 3.前序循環(huán)遍歷T
void LoopPostOrderTraverse(BiTree T) {
    if (!T) return;
    // 這里偷懶知道樹高5
    int top = -1;
    BiTNode **stack = (BiTNode **)malloc(sizeof(BiTNode*) * 5);
    BiTNode *cur = T, *recent = NULL;
    while (cur || top > -1) {
        if (cur) { //走到最左邊
            stack[++top] = cur;
            cur = cur->lchild;
        } else {
            cur = stack[top];
            if (cur->rchild && cur->rchild != recent) //右子樹存在,未被訪問
                cur = cur->rchild;
            else {
                --top;
                printf("%c", cur->data); // 顯示結(jié)點(diǎn)數(shù)據(jù)
                recent = cur; //記錄最近訪問過的節(jié)點(diǎn)
                cur = NULL; //節(jié)點(diǎn)訪問完后演训,重置p指針
            }
        }
    }
    free(stack);
}

// 檢驗(yàn)
int main(int argc, const char * argv[]) {
    BiTree T;
    CElemType e1;
    /*
                A
           B        C
         D   E     F   G
        H # # #   I # # J
       # K       # #   # #
        # #
     ABDH#K###E##CFI###G#J##
     */
    
    InitBiTree(&T);
    StrAssign(str,"ABDH#K###E##CFI###G#J##");
    CreateBiTree(&T);
    
    printf("遞歸前序遍歷二叉樹:");
    PreOrderTraverse(T);
    printf("\n遞歸中序遍歷二叉樹:");
    InOrderTraverse(T);
    printf("\n遞歸后序遍歷二叉樹:");
    PostOrderTraverse(T);
    
    printf("\n循環(huán)前序遍歷二叉樹:");
    LoopPreOrderTraverse(T);
    printf("\n循環(huán)中序遍歷二叉樹:");
    LoopInOrderTraverse(T);
    printf("\n循環(huán)后序遍歷二叉樹:");
    LoopPostOrderTraverse(T);
  
    printf("\n");
    return 0;
}
// 輸出
遞歸前序遍歷二叉樹:ABDHKECFIGJ
遞歸中序遍歷二叉樹:HKDBEAIFCGJ
遞歸后序遍歷二叉樹:KHDEBIFJGCA
循環(huán)前序遍歷二叉樹:ABDHKECFIGJ
循環(huán)中序遍歷二叉樹:HKDBEAIFCGJ
循環(huán)后序遍歷二叉樹:KHDEBIFJGCA
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贝咙,一起剝皮案震驚了整個(gè)濱河市样悟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖陈症,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件震糖,死亡現(xiàn)場(chǎng)離奇詭異录肯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吊说,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門论咏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颁井,“玉大人,你說我怎么就攤上這事雅宾。” “怎么了眉抬?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蜀变,是天一觀的道長悄谐。 經(jīng)常有香客問我库北,道長,這世上最難降的妖魔是什么洼专? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任孵构,我火速辦了婚禮,結(jié)果婚禮上颈墅,老公的妹妹穿的比我還像新娘。我一直安慰自己官还,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布望伦。 她就那樣靜靜地躺著,像睡著了一般腿箩。 火紅的嫁衣襯著肌膚如雪劣摇。 梳的紋絲不亂的頭發(fā)上珠移,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天钧惧,我揣著相機(jī)與錄音勾习,去河邊找鬼浓瞪。 笑死语卤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酪刀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼眼滤,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼历涝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荧库,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤分衫,失蹤者是張志新(化名)和其女友劉穎场刑,沒想到半個(gè)月后蚪战,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞎疼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年贼急,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茅茂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡玉吁,死狀恐怖腻异,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情影斑,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布矫户,位于F島的核電站残邀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏芥挣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一空另、第九天 我趴在偏房一處隱蔽的房頂上張望蹋砚。 院中可真熱鬧,春花似錦坝咐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咪辱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間历恐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工弱贼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒸苇,地道東北人吮旅。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像檬嘀,于是被迫代替她去往敵國和親责嚷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鸳兽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349