2020-11-23--二叉樹詳解!詳細(xì)闡述二叉樹基本概念、二叉樹遍歷實現(xiàn)以及非遞歸遍歷實現(xiàn)等等(干貨滿滿)

https://www.bilibili.com/video/BV15a4y1a7B5?from=search&seid=1889880629413614926

image.png

image.png

image.png

image.png

image.png

image.png

29:13秒


image.png

image.png

比較完整的代碼:
image.png

image.png

image.png

image.png

image.png

image.png

image.png

=========================
========================用棧遞歸的方法。
56分鐘:


image.png

========================
遇到了問題:
https://www.cnblogs.com/hiloves/p/4678848.html
error LNK2019: 無法解析的外部符號

https://www.cnblogs.com/imzhstar/p/4110870.html
http://www.itdecent.cn/p/7df6e7194d02
這個方法靠譜,測試成功了!

image.png

image.png

版本一,3中遍歷方式,前序,中序,后序

//#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <locale.h>

//遇到了一個難題,解決辦法:http://www.itdecent.cn/p/7df6e7194d02

//描述單一個體
typedef struct treeNode
{
    char data;   //數(shù)據(jù)域字符表示
    struct treeNode* LChild;
    struct treeNode* RChild;
    

}TREE,*LPTREE;


LPTREE createNode(char data )
{
    LPTREE newNode = (LPTREE)malloc(sizeof(TREE));
    newNode->data = data;
    newNode->LChild = NULL;
    newNode->RChild = NULL;
    return newNode;
}

//沒有規(guī)律的樹
void insertNode(LPTREE parentNode, LPTREE LChild, LPTREE RChild)
{
    parentNode->LChild = LChild;
    parentNode->RChild = RChild;
}
void printCurNodeData(LPTREE CurData )
{
    printf("%c\t", CurData->data);
}

//遞歸法;領(lǐng)悟
//前序,根,左,右
void preOrder(LPTREE root )
{
    if (root!=NULL )
    {
        printCurNodeData(root);   //根
        preOrder(root->LChild);   //左
        preOrder(root->RChild);   //右       
    } 
}
//左序:左,根,右
void MidOrder(LPTREE root)
{
    if (root != NULL)
    {
        
        MidOrder(root->LChild);   //左
        printCurNodeData(root);   //根
        MidOrder(root->RChild);   //右       
    }
}

//后序:左,根,右
void lastOrder(LPTREE root)
{
    if (root != NULL)
    {

        lastOrder(root->LChild);   //左
        lastOrder(root->RChild);   //右      
        printCurNodeData(root);   //根
    }
}




int main()
{
    //死板的創(chuàng)建過程,無任何實際意義
    LPTREE A = createNode('A');
    LPTREE B = createNode('B');
    LPTREE C = createNode('C');
    LPTREE D = createNode('D');
    LPTREE E = createNode('E');
    LPTREE F = createNode('F');
    LPTREE G = createNode('G');
    insertNode(A, B, C);
    insertNode(B, D, NULL);
    insertNode(D, NULL, G);
    insertNode(C, E, F);

    printf("前序遍歷:\n");
    preOrder(A);
    printf("\n中序遍歷:\n");
    MidOrder(A);
    printf("\n后序遍歷:\n");
    lastOrder(A);


    system("pause");
    return 0;

}

結(jié)果如圖所示:


image.png

接下來,用非遞歸方法,中序方法遍歷節(jié)點。


image.png

最終結(jié)果,2個方法遍歷,遞歸和非遞歸都成功了,代碼如下:

//#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <locale.h>

//遇到了一個難題,解決辦法:http://www.itdecent.cn/p/7df6e7194d02


//描述單一個體
typedef struct treeNode
{
    char data;   //數(shù)據(jù)域字符表示
    struct treeNode* LChild;
    struct treeNode* RChild;
    

}TREE,*LPTREE;


LPTREE createNode(char data )
{
    LPTREE newNode = (LPTREE)malloc(sizeof(TREE));
    newNode->data = data;
    newNode->LChild = NULL;
    newNode->RChild = NULL;
    return newNode;
}

//沒有規(guī)律的樹
void insertNode(LPTREE parentNode, LPTREE LChild, LPTREE RChild)
{
    parentNode->LChild = LChild;
    parentNode->RChild = RChild;
}
void printCurNodeData(LPTREE CurData )
{
    printf("%c\t", CurData->data);
}

//遞歸法;領(lǐng)悟
//前序,根,左,右
void preOrder(LPTREE root )
{
    if (root!=NULL )
    {
        printCurNodeData(root);   //根
        preOrder(root->LChild);   //左
        preOrder(root->RChild);   //右       
    } 
}
//前序遍歷,采用棧方式,非遞歸方式遍歷
void preOrderByStack(LPTREE root)
{
    if (root == NULL)
    {
        return;
    }
    //準(zhǔn)備一個棧
    LPTREE stack[10];      //結(jié)構(gòu)體指針,用來存放節(jié)點的位置。存儲每次打印的節(jié)點的位置
    //  struct treeNode* stack[10];

    int stackTop = -1;     //棧頂標(biāo)記,等于-1,是為了跟數(shù)組下標(biāo)保持一致而已
    LPTREE pMove = root;     //從根節(jié)點開始打印
    while (stackTop != -1 || pMove)   //當(dāng)棧中沒有路徑可以退,或者當(dāng)前節(jié)點不等于空的時候,
    {
        //根,左,右
        //找到最左邊
        while (pMove)
        {
            //把路徑入棧+打印走過的節(jié)點
            printf("%c\t", pMove->data);
            stack[++stackTop] = pMove;
            pMove = pMove->LChild;
        }
        //無路可走的處理
        if (stackTop != -1)
        {
            pMove = stack[stackTop];     //獲取棧頂元素
            stackTop--;                  //這個才是出棧操作
            pMove = pMove->RChild;       //找右邊的
        }
    }

}


//中序:左,根,右
void MidOrder(LPTREE root)
{
    if (root != NULL)
    {
        
        MidOrder(root->LChild);   //左
        printCurNodeData(root);   //根
        MidOrder(root->RChild);   //右       
    }
}

void MidOrderByStack(LPTREE root)
{
    if (root == NULL)
    {
        return;
    }
    //棧的準(zhǔn)備動作
    struct treeNode* stack[10];
    int stackTop = -1;

    //定義的移動的指針
    LPTREE pMove = root;
    while (stackTop!= -1||pMove )
    {
        //走到最左邊,把走過的結(jié)點入棧
        while (pMove )
        {
            stack[++stackTop] = pMove;
            pMove = pMove->LChild;
        }
        //出棧
        if (stackTop!=-1 )
        {
            pMove = stack[stackTop--];
            printf("%c \t", pMove->data);
            pMove = pMove->RChild;

        }
    }

}

//后序:左,根,右
void lastOrder(LPTREE root)
{
    if (root != NULL)
    {

        lastOrder(root->LChild);   //左
        lastOrder(root->RChild);   //右      
        printCurNodeData(root);   //根
    }
}

void lastOrderByStack(LPTREE root)
{
    if (root == NULL)
    {
        return;
    }
    struct treeNode* Stack[10];
    int stackTop = -1;

    struct treeNode* pMove = root;
    struct treeNode* pLastVisit = NULL;      //訪問標(biāo)記

    //左,右,根
    while (pMove)
    {
        Stack[++stackTop] = pMove;
        pMove = pMove->LChild;
    }
    while (stackTop!=-1 )
    {
        pMove = Stack[stackTop--];

        //當(dāng)前節(jié)點左右是否被訪問
        if (pMove->RChild == NULL || pMove->RChild == pLastVisit)
        {
            //左,右,根
            //如果被訪問,就可以打印當(dāng)前節(jié)點數(shù)據(jù)
            printf("%c\t", pMove->data);
            pLastVisit = pMove;        //改變標(biāo)記的位置
        }
        else
        {
            //右邊沒有被訪問
            Stack[++stackTop] = pMove;
            pMove = pMove->RChild;
            while (pMove)
            {
                Stack[++stackTop] = pMove;
                pMove = pMove->LChild;
            }

        }
    }


}





int main()
{
    //死板的創(chuàng)建過程,無任何實際意義
    LPTREE A = createNode('A');
    LPTREE B = createNode('B');
    LPTREE C = createNode('C');
    LPTREE D = createNode('D');
    LPTREE E = createNode('E');
    LPTREE F = createNode('F');
    LPTREE G = createNode('G');
    insertNode(A, B, C);
    insertNode(B, D, NULL);
    insertNode(D, NULL, G);
    insertNode(C, E, F);

    printf("前序遍歷:\n");
    preOrder(A);
    printf("\n");
    preOrderByStack(A);



    printf("\n中序遍歷:\n");
    MidOrder(A);
    printf("\n");
    MidOrderByStack(A);


    printf("\n后序遍歷:\n");
    lastOrder(A);
    printf("\n");
    lastOrderByStack(A);


    system("pause");
    return 0;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容