国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數據結構】二叉樹的鏈式存儲結構

這篇具有很好參考價值的文章主要介紹了【數據結構】二叉樹的鏈式存儲結構。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【數據結構】二叉樹的鏈式存儲結構

二叉樹的存儲結構

typedef int BTDataType;
// 二叉樹的結構
typedef struct BinaryTreeNode {
    BTDataType data;             // 樹的值
    struct BinaryTreeNode *left; // 左孩子
    struct BinaryTreeNode *right;// 右孩子
} BinaryTreeNode;

二叉樹的深度優(yōu)先遍歷

【數據結構】二叉樹的鏈式存儲結構,數據結構,數據結構,算法,c++,stl

前序遍歷

前序遍歷,又叫先根遍歷。
遍歷順序:根 -> 左子樹 -> 右子樹

代碼:

// 前序遍歷
void BinaryTreePrevOrder(BinaryTreeNode *root) {
    // 前序遍歷 根、左子樹、右子樹
    // 如果root為空,遞歸結束
    if (root == NULL) {
        printf("NULL ");
        return;
    }

    printf("%d ", root->data);
    BinaryTreePrevOrder(root->left);
    BinaryTreePrevOrder(root->right);
}

中序遍歷

中序遍歷,又叫中根遍歷。
遍歷順序:左子樹 -> 根 -> 右子樹

代碼

// 中序遍歷
void BinaryTreeInOrder(BinaryTreeNode *root) {
    // 中序遍歷 - 左子樹、根、右子樹
    if (root == NULL) {
        printf("NULL ");
        return;
    }
    BinaryTreeInOrder(root->left);
    printf("%d ", root->data);
    BinaryTreeInOrder(root->right);
}

后序遍歷

后序遍歷,又叫后根遍歷。
遍歷順序:左子樹 -> 右子樹 -> 根

代碼

// 后序遍歷
void BinaryPostOrder(BinaryTreeNode *root) {
    // 后序遍歷 - 左子樹、右子樹、根
    if (root == NULL) {
        printf("NULL ");
        return;
    }
    BinaryPostOrder(root->left);
    BinaryPostOrder(root->right);
    printf("%d ", root->data);
}

二叉樹的廣度優(yōu)先遍歷

層序遍歷

除了先序遍歷、中序遍歷、后序遍歷外,還可以對二叉樹進行層序遍歷。設二叉樹的根節(jié)點所在層數為1,層序遍歷就是從所在二叉樹的根節(jié)點出發(fā),首先訪問第一層的樹根節(jié)點,然后從左到右訪問第2層 上的節(jié)點,接著是第三層的節(jié)點,以此類推,自上而下,自左至右逐層訪問樹的結點的過程就是層序遍歷。

【數據結構】二叉樹的鏈式存儲結構,數據結構,數據結構,算法,c++,stl

思路(借助一個隊列):

  1. 先把根入隊列,然后開始從隊頭出數據。
  2. 出隊頭的數據,把它的左孩子和右孩子依次從隊尾入隊列(NULL不入隊列)。
  3. 重復進行步驟2,直到隊列為空為止。

【數據結構】二叉樹的鏈式存儲結構,數據結構,數據結構,算法,c++,stl

特點:借助隊列先進先出的性質,上一層數據出隊列的時候帶入下一層數據。

// 層序遍歷 - 利用隊列
void BinaryTreeLevelOrder(BinaryTreeNode *root) {
    // 創(chuàng)建一個隊列,隊列中入數據,取隊頭,然后帶左右子樹,出一個數,帶一個樹的所有子樹
    Queue q;
    QueueInit(&q);
    if (root) {
        // root不為NULL,就入隊列
        QueuePush(&q, root);
    }

    while (!QueueEmpty(&q)) {
        // 取隊頭,打印
        BinaryTreeNode *front = QueueFront(&q);
        printf("%d ", front->data);

        // 取完POP
        QueuePop(&q);
        // 取隊頭,帶下一層,
        if (front->left) {
            QueuePush(&q, front->left);
        }

        if (front->right) {
            QueuePush(&q, front->right);
        }
    }
    printf("\n");
    QueueDestroy(&q);
}

二叉樹的節(jié)點個數

求解樹的節(jié)點總數時,可以將問題拆解成子問題:

  1. 若為空,則結點個數為0。
  2. 若不為空,則結點個數 = 左子樹節(jié)點個數 + 右子樹節(jié)點個數 + 1(自己)。

代碼

// 求二叉樹節(jié)點個數
int BinaryTreeSize(BinaryTreeNode *root) {
    if (root == NULL) {
        return 0;
    }
    return 1 + BinaryTreeSize(root->left) + BinaryTreeSize(root->right);
}

二叉樹的葉子節(jié)點個數

子問題拆解:

  1. 若為空,則葉子結點個數為0。
  2. 若結點的左指針和右指針均為空,則葉子結點個數為1。
  3. 除上述兩種情況外,說明該樹存在子樹,其葉子結點個數 = 左子樹的葉子結點個數 + 右子樹的葉子結點個數。

代碼:

// 求二叉樹的葉子節(jié)點個數
int BinaryTreeLeafSize(BinaryTreeNode *root) {
    if (root == NULL) {
        return 0;
    }

    if (root->left == NULL && root->right == NULL) {
        return 1;
    }

    return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
}

第K層節(jié)點的個數

思路:
相對于根結點的第k層結點的個數 = 相對于以其左孩子為根的第k-1層結點的個數 + 相對于以其右孩子為根的第k-1層結點的個數。

【數據結構】二叉樹的鏈式存儲結構,數據結構,數據結構,算法,c++,stl

代碼

// 求第k層的節(jié)點個數 k>=1
int BinaryTreeLevelSize(BinaryTreeNode *root, int k) {
    if (root == NULL) {
        return 0;
    }

    if (k == 1) {
        return 1;
    }

    return BinaryTreeLevelSize(root->left, k - 1) + BinaryTreeLevelSize(root->right, k - 1);
}

值為x的節(jié)點

子問題:

  1. 先判斷根結點是否是目標結點。
  2. 再去左子樹中尋找。
  3. 最后去右子樹中尋找。

代碼

// 二叉樹查找值為x的節(jié)點
BinaryTreeNode *BinaryTreeFind(BinaryTreeNode *root, BTDataType x) {
    if (root == NULL) {
        return NULL;
    }

    if (root->data == x) {
        return root;
    }

    // 左子樹遞歸的節(jié)點保存到leftTree中,如果leftTree不為NULL,則return leftTree
    BinaryTreeNode *leftTree = BinaryTreeFind(root->left, x);
    if (leftTree) {
        return leftTree;
    }

    // 右子樹遞歸的節(jié)點保存到rightTree中,如果rightTree不為NULL,則return rightTree
    BinaryTreeNode *rightTree = BinaryTreeFind(root->right, x);
    if (rightTree) {
        return rightTree;
    }

    // 找不到,返回NULL
    return NULL;
}

樹的高度

子問題:

  1. 若為空,則深度為0。
  2. 若不為空,則樹的最大深度 = 左右子樹中深度較大的值 + 1。

代碼

// 求二叉樹的高度
int BinaryTreeHeight(BinaryTreeNode *root) {
    // 求左子樹的高度,右子樹的高度
    // 取最大的
    if (root == NULL) {
        return 0;
    }
    int leftHeight = BinaryTreeHeight(root->left);
    int rightHeight = BinaryTreeHeight(root->right);
	
	//如果左右子樹兩邊相等就取左邊的高度,所以大于等于
    return leftHeight >= rightHeight ? leftHeight + 1 : rightHeight + 1;
}

判斷二叉樹是否是完全二叉樹

判斷二叉樹是否是完全二叉樹的方法與二叉樹的層序遍歷類似,但又有一些不同。

思路(借助一個隊列):

  1. 先把根入隊列,然后開始從隊頭出數據。
  2. 出隊頭的數據,把它的左孩子和右孩子依次從隊尾入隊列(NULL也入隊列)。
  3. 重復進行步驟2,直到讀取到的隊頭數據為NULL時停止入隊列。
  4. 檢查隊列中剩余數據,若全為NULL,則是完全二叉樹;若其中有一個非空的數據,則不是完全二叉樹。

【數據結構】二叉樹的鏈式存儲結構,數據結構,數據結構,算法,c++,stl

代碼

// 判斷二叉樹是否是完全二叉樹
bool BinaryTreeComplete(BinaryTreeNode *root) {
    // 層序走,走到第一個為空的時候,就跳出去,如果是滿二叉樹,后面的節(jié)點都應該為空
    Queue q;
    QueueInit(&q);
    if (root) {
        QueuePush(&q, root);
    }

    while (!QueueEmpty(&q)) {
        BinaryTreeNode *front = QueueFront(&q);
        QueuePop(&q);

        if (front == NULL) {
            break;
        } else {
            QueuePush(&q, front->left);
            QueuePush(&q, front->right);
        }
    }
    // 出到空以后,如果后面全是空,則是完全二叉樹
    while (!QueueEmpty(&q)) {
        BinaryTreeNode *front = QueueFront(&q);
        QueuePop(&q);
        if (front != NULL) {
            QueueDestroy(&q);
            return false;
        }
    }
    QueueDestroy(&q);
    return true;
}

判斷二叉樹是否是單值二叉樹

單值二叉樹,所有節(jié)點的值都相同的二叉樹即為單值二叉樹,判斷某一棵二叉樹是否是單值二叉樹的一般步驟如下:

  1. 判斷根的左孩子的值與根結點是否相同。
  2. 判斷根的右孩子的值與根結點是否相同。
  3. 判斷以根的左孩子為根的二叉樹是否是單值二叉樹。
  4. 判斷以根的右孩子為根的二叉樹是否是單值二叉樹。

若滿足以上情況,則是單值二叉樹。

注:空樹也是單值二叉樹。

代碼

//求單值二叉樹
bool isUnivalTree(BinaryTreeNode *root) {
    if (root == nullptr) {
        return true;
    }

    if (root->left && root->data != root->left->data) {
        return false;
    }
    
	if (root->right && root->data != root->right->data) {
        return false;
    }

    return isUnivalTree(root->left) && isUnivalTree(root->right);
}

判斷二叉樹是否是對稱二叉樹

對稱二叉樹,這里所說的對稱是指鏡像對稱:

要判斷某二叉樹是否是對稱二叉樹,則判斷其根結點的左子樹和右子樹是否是鏡像對稱即可。因為是鏡像對稱,所以左子樹的遍歷方式和右子樹的遍歷方式是不同的,準確來說,左子樹和右子樹的遍歷是反方向進行的。

代碼

//求對稱二叉樹
bool _isSymmetric(BinaryTreeNode *left, BinaryTreeNode *right) {
    // 兩個都為NULL,對稱
    if (left == NULL && right == NULL)
        return true;

    // 兩個其中一個為NULL,一個不為NULL,不對稱
    if (left == NULL || right == NULL)
        return false;

    // left的左孩子的值和right的值不相等,不對稱
    if (left->data != right->data)
        return false;

    // 左子樹的左孩子,和右子樹的右孩子對比,然后左子樹的右孩子和右子樹的左孩子在對比
    return _isSymmetric(left->left, right->right) && _isSymmetric(left->right, right->left);
}

bool isSymmetric(BinaryTreeNode *root) {
    if (root == nullptr) {
        return true;
    }

    return _isSymmetric(root->left, root->right);
}

翻轉二叉樹

思路:

  1. 翻轉左子樹。
  2. 翻轉右子樹。
  3. 交換左右子樹的位置。

代碼

BinaryTreeNode *invertTree(BinaryTreeNode *root) {
    if (root == nullptr) {
        return nullptr;
    }

    BinaryTreeNode *leftTree = invertTree(root->left);
    BinaryTreeNode *rightTree = invertTree(root->right);

    root->left = rightTree;
    root->right = leftTree;

    return root;
}

二叉樹的構建和銷毀

// 申請樹節(jié)點
BinaryTreeNode *BuyBinaryTreeNode(BTDataType x) {
    BinaryTreeNode *newnode = (BinaryTreeNode *) malloc(sizeof(BinaryTreeNode));
    if (newnode == NULL) {
        perror("malloc fail");
        exit(-1);
    }
    newnode->data = x;
    newnode->left = newnode->right = NULL;
    return newnode;
}

// 通過前序遍歷的數組"ABD##E#H##CF##G##"構建二叉樹
BinaryTreeNode *BinaryTreeCreate(BTDataType *a, int *pi) {
    if (a[*pi] == '#') {
        (*pi)++;
        return NULL;
    }

    BinaryTreeNode *root = (BinaryTreeNode *) malloc(sizeof(BinaryTreeNode));
    if (root == NULL) {
        perror("malloc fail");
        exit(-1);
    }
    root->data = a[(*pi)++];

    root->left = BinaryTreeCreate(a, pi);
    root->right = BinaryTreeCreate(a, pi);
    return root;
}

銷毀文章來源地址http://www.zghlxwxcb.cn/news/detail-706871.html

// 二叉樹銷毀
void BinaryTreeDestory(BinaryTreeNode **root) {
    if (*root == NULL) {
        return;
    }
    // 后序遍歷銷毀,根要最后釋放
    BinaryTreeDestory(&(*root)->left);
    BinaryTreeDestory(&(*root)->right);
    free(*root);
    *root = NULL;
}

到了這里,關于【數據結構】二叉樹的鏈式存儲結構的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 數據結構——二叉樹的鏈式結構

    數據結構——二叉樹的鏈式結構

    ? 個人主頁 : 日刷百題 系列專欄 : 〖C語言小游戲〗〖Linux〗〖數據結構〗 ?〖C語言〗 ?? 歡迎各位 → 點贊 ??+ 收藏 ??+ 留言 ??? ? 這里我們使用先序遍歷的思想來創(chuàng)建二叉樹,這里的內容對于剛接觸二叉樹的朋友可能有些難理解,不妨先看完下面的二叉樹各種遍歷

    2024年02月05日
    瀏覽(31)
  • 【數據結構】二叉樹的鏈式結構

    【數據結構】二叉樹的鏈式結構

    學習鏈式二叉樹要知道三種遍歷方式,便于對二叉樹的節(jié)點以及左子樹和右子樹進行操作。 前序遍歷:根、左子樹、右子樹 中序遍歷:左子樹、根、右子樹 后序遍歷:左子樹、右子樹、根 以下圖為例: 得到的結果: 前序遍歷:1 2 3 4 5 6 中序遍歷:3 2 1 5 4 6 后序遍歷:3 2

    2024年02月08日
    瀏覽(29)
  • 數據結構:二叉樹的鏈式結構

    數據結構:二叉樹的鏈式結構

    朋友們、伙計們,我們又見面了,本期來給大家解讀一下鏈式二叉樹的相關知識點,如果看完之后對你有一定的啟發(fā),那么請留下你的三連,祝大家心想事成! 數據結構與算法專欄 :數據結構與算法 個? 人? 主? 頁 :stackY、 C 語 言 專 欄 :C語言:從入門到精通 目錄 前言

    2024年02月07日
    瀏覽(22)
  • 【數據結構—二叉樹的鏈式結構實現】

    【數據結構—二叉樹的鏈式結構實現】

    提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言 一、二叉樹的存儲結構 二、二叉樹鏈式結構的實現 2.1手動構建一課樹 2.2二叉樹的遍歷 三、二叉樹鏈式結構的實現 3.1前序遍歷(遞歸) 3.2中序遍歷(遞歸) 3.3后序遍歷(遞歸) 3.4層序遍歷(非遞

    2024年02月03日
    瀏覽(24)
  • 【數據結構 —— 二叉樹的鏈式結構實現】

    【數據結構 —— 二叉樹的鏈式結構實現】

    樹是一種非線性的數據結構,它是由n(n=0)個有限結點組成一個具有層次關系的集合。 把它叫做樹是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。 1.有一個 特殊的結點,稱為根結點 ,根節(jié)點沒有前驅結點 2.除根節(jié)點外, 其余結點被分成M(M0)個互不相交

    2024年02月05日
    瀏覽(27)
  • 數據結構初階--二叉樹的鏈式結構

    數據結構初階--二叉樹的鏈式結構

    目錄 一.二叉樹鏈式結構的概念 二.二叉樹鏈式結構的功能實現 2.1.鏈式二叉樹的定義 2.2.鏈式二叉樹的構建 2.3.鏈式二叉樹的遍歷 2.3.1.先序遍歷 2.3.2.中序遍歷 2.3.3.后序遍歷 2.3.4.層序遍歷 2.4.鏈式二叉樹的求二叉樹的結點數量 法一:計數法 法二:分治法 2.5.鏈式二叉樹的求二

    2024年02月12日
    瀏覽(28)
  • 數據結構:二叉樹的鏈式結構的實現

    ? 目錄 ?1.通過前序遍歷構建二叉樹 2.?二叉樹的銷毀 ?3.二叉樹的遍歷 4.?二叉樹的節(jié)點個位和二叉樹的葉子節(jié)點個位數 5.?二叉樹的的k層節(jié)點數和查找值為x的節(jié)點 6.?判斷二叉樹是否為完全二叉樹和求二叉樹的高度h 二叉樹的前序遍歷 二叉樹的中序遍歷 二叉樹的后序遍歷

    2024年02月12日
    瀏覽(30)
  • 【數據結構】二叉樹的鏈式結構及實現

    【數據結構】二叉樹的鏈式結構及實現

    目錄 1. 前置說明 2. 二叉樹的遍歷 2.1 前序、中序以及后序遍歷 2.2 層序遍歷 3.?節(jié)點個數及高度等 4. 二叉樹的創(chuàng)建和銷毀 在學習二叉樹的基本操作前,需先要創(chuàng)建一棵二叉樹,然后才能學習其相關的基本操作。由于現在大家對二叉樹結構掌握還不夠深入,為了降低大家學習成

    2024年02月08日
    瀏覽(25)
  • 【數據結構】二叉樹的鏈式結構的實現 -- 詳解

    【數據結構】二叉樹的鏈式結構的實現 -- 詳解

    在學習二叉樹的基本操作前,需先要創(chuàng)建一棵二叉樹,然后才能學習其相關的基本操作。為了降低大家學習成本,此處手動快速創(chuàng)建一棵簡單的二叉樹,快速進入二叉樹操作學習。 注意 :上述代碼并不是創(chuàng)建二叉樹的方式。 學習二叉樹結構,最簡單的方式就是遍歷。所謂

    2024年02月12日
    瀏覽(28)
  • 【數據結構】二叉樹的鏈式實現及遍歷

    【數據結構】二叉樹的鏈式實現及遍歷

    后文所有代碼中的二叉樹結點: 前,中,后序遍歷都可以采用分治遞歸的思想解決,將根節(jié)點和它的孩子結點分別處理。 此處僅利用遞歸展開圖分析前序遍歷,中序和后序也是相同的思想: 層序遍歷需要利用隊列來進行,如果二叉樹跟結點不為空,則讓 指向它的一個指針入

    2024年02月07日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包