二叉樹:創建,遍歷(遞歸、非遞歸、層次)

廢話不多說,直接堆代碼。

Tree.h

typedef struct TreeNode{
    struct TreeNode* lchild;
    struct TreeNode* rchild;
    char data;
}TreeNode;

main.cpp

#include<stdio.h>
#include<stdlib.h>

#include"Tree.h"

TreeNode* LCreateTree();                            //創建二叉樹

void FrontTraversal(TreeNode* t, int &numOfNode);   //前序遍歷二叉樹 遞歸
void MidTraversal(TreeNode* t);                     //中序遍歷二叉樹
void BackTraversal(TreeNode* t);                    //後序遍歷二叉樹

void FrontTraversal_s(TreeNode* t, int numOfNode);  //前序遍歷二叉樹 非遞歸
void MidTraversal_s(TreeNode* t, int numOfNode);    //中序遍歷二叉樹
void BackTraversal_s(TreeNode* t, int numOfNode);   //後序遍歷二叉樹

void LevelTraversal(TreeNode* t, int numOfNode);    //層次遍歷二叉樹



int main() {

    TreeNode* root;
    root = LCreateTree();               //前序創建二叉樹

    int numOfNode = 0;                  //記錄二叉樹結點個數

    //遞歸方法
    FrontTraversal(root, numOfNode);    //前序遍歷二叉樹
    MidTraversal(root);                 //中序遍歷二叉樹
    BackTraversal(root);                //後序遍歷二叉樹
    printf("%d\n", numOfNode);

    //非遞歸方法
    FrontTraversal_s(root, numOfNode);  //前序遍歷二叉樹
    MidTraversal_s(root, numOfNode);    //中序遍歷二叉樹
    BackTraversal_s(root, numOfNode);   //後序遍歷二叉樹

    LevelTraversal(root,numOfNode); //層次遍歷二叉樹

    return 0;
}


TreeNode* LCreateTree() {           //前序遍歷二叉樹
    char c;
    TreeNode* t;
    c = getchar();
    if (c == '#')
        return NULL;
    else {
        t = (TreeNode*)malloc(sizeof(TreeNode));
        t->data = c;
        t->lchild = LCreateTree();
        t->rchild = LCreateTree();
    }
    return t;
}

void FrontTraversal(TreeNode* t, int &numOfNode) {
    TreeNode* p = t;
    if (p) {
        printf("%c ", p->data);
        numOfNode++;
        FrontTraversal(p->lchild, numOfNode);
        FrontTraversal(p->rchild, numOfNode);
    }
}

void MidTraversal(TreeNode* t) {
    TreeNode* p = t;
    if (p) {
        MidTraversal(p->lchild);
        printf("%c ", p->data);
        MidTraversal(p->rchild);
    }
}

void BackTraversal(TreeNode* t) {
    TreeNode* p = t;
    if (p) {
        BackTraversal(p->lchild);
        BackTraversal(p->rchild);
        printf("%c ", p->data);
    }
}

void FrontTraversal_s(TreeNode* t, int numOfNode) {     //分治,對於每一個結點,先輸出它的記錄
    TreeNode* stack;                                    //然後壓入右孩子,最後壓入左孩子
    stack = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
    int top = -1;
    TreeNode* p;
    p = (TreeNode*)malloc(sizeof(TreeNode));
    if (t != NULL) {
        top++;
        stack[top] = *t;
        while (top > -1) {
            *p = stack[top];
            top--;
            printf("%c ", p->data);
            if (p->rchild) {                //壓入右結點
                top++;
                stack[top] = *(p->rchild);
            }
            if (p->lchild) {                //壓入左結點
                top++;
                stack[top] = *(p->lchild);
            }
        }
    }
    printf("\n");
    free(stack);
    free(p);
}

void MidTraversal_s(TreeNode* t, int numOfNode) {   //分治,先遍歷到最左的結點,輸出它的記錄,出棧 ---1
    TreeNode* stack;                                //然後看它有沒有右子樹,有重複1,沒有就再取棧頂結點。
    stack = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
    TreeNode* p;
    p = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
    int top = -1;
    if (t) {
        p = t;
        while (top > -1 || p) {
            while (p) {         //遍歷到最左側,同時不停壓棧---1
                top++;
                stack[top] = *p;
                p = p->lchild;
            }
            if (top > -1) {
                p = &stack[top];
                top--;
                printf("%c ", p->data);
                p = (p->rchild);    //右子樹重複1過程
            }
        }
    }
    printf("\n");
    free(stack);
    free(p);
}
void BackTraversal_s(TreeNode* t, int numOfNode) {  //首先要遍歷到最左側,決定一個結點是否輸出的是右孩子---1
    TreeNode* stack[10];                            //如果右孩子爲NULL,由於該結點是最左側(或則它的左子樹已經輸出)的結點,所以直接輸出
    TreeNode* p = NULL;                             //如果右孩子不爲NULL,要判斷右孩子是否已經輸出,如果是,則輸出,否,則讓右孩子經歷步驟1
    TreeNode* b = t;
    int top = -1;
    int sign;
    if (b) {
        do {
            while (b) {     //遍歷到最左側
                top++;
                stack[top] = b;
                b = b->lchild;
            }
            p = NULL;
            sign = 1;
            while (top != -1 && sign) {     //判斷右孩子
                b = stack[top];
                if (b->rchild == p) {       //右子樹已經輸出
                    printf("%c ", b->data);
                    top--;
                    p = b;
                }
                else {                      //右孩子還沒有遍歷
                    b = b->rchild;
                    sign = 0;
                }
            }
        } while (top > -1);
    }
    printf("\n");

}

void LevelTraversal(TreeNode* t, int numOfNode) {       //藉助隊列層次輸出二叉樹
    TreeNode *queue;
    queue = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
    int num = 1;                                        //每次加入隊列的結點個數
    int count = 0;                                      //每次輸出層次的起點
    int size = 0;                                       //中間記錄變量
    TreeNode *p = t;
    if (p) {
        queue[count] = *p;
        while(num > 0) {
            for (int j = count; j < count + num; j++)   //從層次的起點輸出num個結點的記錄
                printf("%c ", queue[j].data);
            printf("\n");
            TreeNode temp;
            for (int i = count; i < count + num;) {     //輸出完一層後,得壓入新的一層結點
                temp = queue[i];
                if (temp.lchild) {                      //壓入已輸出層結點的左孩子
                    queue[count + num + size] = *temp.lchild;
                    size++;
                }
                if (temp.rchild) {                      //壓入已輸出層結點的右孩子
                    queue[count + num + size] = *temp.rchild;   
                    size++;
                }
                i++;    
            }
            count += num;                               //層次起點更換
            num = size;                                 //新層次的結點數更換
            size = 0;                                   //臨時記錄歸0
        }
    }
}

這裏寫圖片描述

這裏寫圖片描述

發佈了76 篇原創文章 · 獲贊 83 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章