C++的數據結構(五):樹和存儲結構及示例

????????在計算機科學中,樹是一種抽象數據類型(ADT)或是實現這種抽象數據類型的數據結構,用來模擬具有樹狀結構性質的數據集合。這種數據結構以一系列連接的節點來形成樹形結構。在C++中,樹的概念和存儲結構是實現各種復雜算法和數據操作的基礎。???

?????樹是由節點和邊組成的圖,其中每個節點有零個或多個子節點,但只有一個父節點(除了根節點,它沒有父節點)。樹的頂部節點稱為根節點。如果一個節點沒有子節點,那么它被稱為葉子節點。除了根節點和葉子節點之外的其他節點稱為內部節點。由樹的根節點和若干棵子樹所構成的樹稱為森林。如下圖所示。

?????????樹的術語:? ??

????????(1)路徑:在兩個節點之間,一系列的邊和節點的組合。路徑的長度是組成路徑的邊數。

????????(2)深度:一個節點的深度是指從根節點到該節點的最長路徑上的邊數。根節點的深度為0。

????????(3)層次:樹的層次從根開始定義,根為第一層,根的子節點為第二層,以此類推。

????????(4)高度:樹的高度是從葉子節點開始自底向上逐層累加的路徑上邊的數量。根節點的高度就是樹的高度。

????????在C++中,樹的存儲結構主要有兩種:順序存儲和鏈式存儲。不同的存儲結構對應著不同的表示方法,如孩子表示法、雙親表示法、孩子兄弟表示法等。

????????1. 順序存儲:順序存儲通常用于完全二叉樹。在完全二叉樹中,除了最后一層外,其他層的節點數是滿的,并且最后一層的節點都靠左排列。這種特性使得完全二叉樹可以使用數組進行順序存儲,其中每個節點的索引與其在樹中的位置相關。

? ? ? ? 示例:創建一棵簡單的完全二叉樹,代碼如下。

#include <iostream>
#include <vector>using namespace std;class TreeNode {
public:int value;TreeNode* left;TreeNode* right;TreeNode(int x) : value(x), left(nullptr), right(nullptr) {}
};class BinaryTree {
private:vector<TreeNode*> nodes;
public:// 初始化樹的根節點void initRoot(int value) {nodes.push_back(new TreeNode(value));}// 添加子節點void addChild(int parentIndex, int leftChildValue, int rightChildValue) {int nextEmptyIndex = nodes.size();if (leftChildValue != -1) {nodes.push_back(new TreeNode(leftChildValue));nodes[parentIndex]->left = nodes[nextEmptyIndex];}if (rightChildValue != -1) {nodes.push_back(new TreeNode(rightChildValue));nodes[parentIndex]->right = nodes[nextEmptyIndex + (leftChildValue != -1)];}}// 示例:創建一棵簡單的完全二叉樹void createExampleTree() {initRoot(1);addChild(0, 2, 3);addChild(1, 4, 5);addChild(2, 6, -1);addChild(3, 7, 8);}// 其他操作,如遍歷、查找等...
};

????????鏈式存儲:鏈式存儲通過節點和指針來表示樹中的關系。每個節點包含數據域和指向其子節點的指針域。鏈式存儲方式更加靈活,適用于各種類型的樹。

? ? ? ? 示例一:使用孩子表示法創建樹,代碼如下。

class TreeNode {
public:int value;vector<TreeNode*> children;TreeNode(int x) : value(x) {}
};// 使用孩子表示法創建樹
TreeNode* createTree() {TreeNode* root = new TreeNode(1);TreeNode* node2 = new TreeNode(2);TreeNode* node3 = new TreeNode(3);TreeNode* node4 = new TreeNode(4);TreeNode* node5 = new TreeNode(5);root->children.push_back(node2);root->children.push_back(node3);node2->children.push_back(node4);node2->children.push_back(node5);return root;
}

????????上述代碼展示了如何使用孩子表示法來創建一個樹,其中每個節點都有一個指向其子節點的指針列表。這種方式可以很直觀地表示一個節點的所有子節點,但是在查找父節點時不夠高效,因為父節點的信息并未存儲在當前節點中。

????????在雙親表示法中,每個節點不僅包含數據域和指向其子節點的指針,還包含一個指向其父節點的指針。這使得我們可以方便地訪問一個節點的父節點,但可能需要額外的空間來存儲父節點的指針。

? ? ? ? 示例二:使用雙親表示法創建樹,代碼如下:

class TreeNode {
public:int value;TreeNode* parent; // 指向父節點的指針vector<TreeNode*> children; // 子節點列表TreeNode(int x) : value(x), parent(nullptr) {}
};// 使用雙親表示法創建樹
void createTreeWithParent(TreeNode*& root) {root = new TreeNode(1); // 根節點的父節點為nullTreeNode* node2 = new TreeNode(2);TreeNode* node3 = new TreeNode(3);TreeNode* node4 = new TreeNode(4);TreeNode* node5 = new TreeNode(5);node2->parent = root;node3->parent = root;node4->parent = node2;node5->parent = node2;root->children.push_back(node2);root->children.push_back(node3);node2->children.push_back(node4);node2->children.push_back(node5);
}

????????在雙親表示法中,我們可以沿著父節點的指針向上遍歷樹,直到找到根節點或者到達一個父節點為空的節點。這種表示法在需要頻繁進行父子節點關系查詢時比較有用。

????????孩子兄弟表示法是一種結合了孩子表示法和雙親表示法的思想的方法。在這種表示法中,每個節點包含指向其第一個孩子節點的指針和指向其下一個兄弟節點的指針。這種表示法對于二叉樹非常自然,并且可以很方便地表示任何類型的樹。
? ? ? ? 示例三:?使用孩子兄弟表示法創建樹,代碼如下:

class TreeNode {
public:int value;TreeNode* firstChild; // 指向第一個孩子節點TreeNode* nextSibling; // 指向下一個兄弟節點TreeNode(int x) : value(x), firstChild(nullptr), nextSibling(nullptr) {}
};// 使用孩子兄弟表示法創建樹
void createTreeWithChildSibling(TreeNode*& root) {root = new TreeNode(1);TreeNode* node2 = new TreeNode(2);TreeNode* node3 = new TreeNode(3);TreeNode* node4 = new TreeNode(4);TreeNode* node5 = new TreeNode(5);root->firstChild = node2;node2->nextSibling = node3;node3->firstChild = node4;node3->nextSibling = node5;
}

????????在這種表示法中,通過firstChild可以訪問到該節點的所有子節點,而通過nextSibling可以遍歷該節點的所有兄弟節點。這種方法特別適合處理那些子節點之間沒有順序要求的樹結構。

????????每種存儲結構都有其適用的場景和優缺點,例如順序存儲適合表示完全二叉樹,而鏈式存儲則更加靈活,能夠表示任意結構的樹。在實際應用中,需要根據具體需求和樹的特點來選擇適當的存儲結構。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11142.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11142.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11142.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java--初識類和對象

前言 本篇講解Java類和對象的入門版本。 學習目的&#xff1a; 1.理解什么是類和對象。 2.引入面向對象程序設計的概念 3.學會如何定義類和創建對象。 4.理解this引用。 5.了解構造方法的概念并學會使用 考慮到篇幅過長問題&#xff0c;作者決定分多次發布。 面向對象的引入 J…

Docker之grep: (standard input): binary file matches

使用 docker compose logs -f | grep 命令時遇到了 grep: (standard input): binary file matches 錯誤。 這個錯誤通常發生在 grep 嘗試搜索包含二進制內容的文件時。docker compose logs 命令會輸出容器的日志&#xff0c;而這些日志可能包含二進制數據&#xff0c;導致 gre…

MySQL查詢篇-集合運算

文章目錄 union &#xff08;并集&#xff09;union distinctunion all intersect(交集)intersect allintersect distinct except 差集except distinctexcept distinctexcept all union &#xff08;并集&#xff09; union distinct 使用前提&#xff1a;a和c數據類型一致&a…

互聯網摸魚日報(2024-05-13)

互聯網摸魚日報(2024-05-13) 36氪新聞 當綠色飛行成為潮流&#xff0c;這家航空公司定下了新目標 | 最前線 回收雨水澆花&#xff0c;廚余垃圾變肥料&#xff0c;我們打卡了阿里北京新園區 | 最前線 本周雙碳大事&#xff1a;中美就氣候問題進行會談&#xff1b;鋰電池行業迎…

GIAT: 蛋白質結構預測的新利器

瑞典Karolinska研究院在瑞典政府贊助下由Ben Murrell等研究團隊在AlphaFold 3最新報告后提出這篇論文提出了一種非常有趣和創新的方法來生成蛋白質骨架結構,稱為生成式不變角度轉換器(GIAT)。與現有的主要基于擴散模型和流匹配的方法不同,GIAT采用了類似于大型語言模型(如GPT)中…

【C語言|數據結構】雙向鏈表

文章目錄 前言1、初步認識雙向鏈表1.1 定義&#xff1a;1.2 結構1.3 節點的存儲 2、雙向鏈表的接口函數2.1 鏈表的節點的動態申請2.2 鏈表的初始化2.3 尾插2.4 頭插2.5 頭刪2.5 尾刪2.6 在pos節點后面添加數據2.6 刪除pos節點 3、雙向鏈表的實現&#xff1a; 前言 各位小伙伴大…

C控制語句:分支和跳轉

1.1if語句 //colddays.c --找出0攝氏度以下的天數占總天數的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…

電子學會C/C++編程等級考試2024年03月(八級)真題解析

C/C編程&#xff08;1~8級&#xff09;全部真題?點這里 第1題&#xff1a;道路 N個以 1 … N 標號的城市通過單向的道路相連:。每條道路包含兩個參數&#xff1a;道路的長度和需要為該路付的通行費&#xff08;以金幣的數目來表示&#xff09; Bob and Alice 過去住在城市 1.在…

藍海創業商機小吃配方項目,日入200+ ,小白可上手,圖文創作轉現快

小吃技術銷售&#xff0c;一單價格從幾元到幾百元不等&#xff0c;行業競爭相對較小&#xff0c;是一個相對冷門的領域。只需一部手機&#xff0c;就可以發布圖文并茂的內容&#xff0c;配上背景音樂&#xff08;BGM&#xff09;&#xff0c;即使是對視頻剪輯不熟悉的新手&…

面試中算法(金礦)

有一位國王擁有5座金礦&#xff0c;每座金礦的黃金儲量不同&#xff0c;需要參與挖掘的工人人數也不同。 例如&#xff0c;有的金礦儲量是5ookg黃金&#xff0c;需要5個工人來挖掘;有的金礦儲量是2ookg黃金&#xff0c;需要3個工人來挖掘...... 如果參與挖礦的工人的總數是10。…

【Oracle impdp導入dmp文件(windows)】

Oracle impdp導入dmp文件&#xff08;windows&#xff09; 1、連接數據庫2、創建與導出的模式相同名稱的用戶WIRELESS2&#xff0c;并賦予權限3、創建directory 的物理目錄f:\radio\dmp&#xff0c;并把.dmp文件放進去4、連接新用戶WIRELESS25、創建表空間的物理目錄F:\radio\t…

試衣不再有界:Tunnel Try-on開啟視頻試衣應用新紀元

論文&#xff1a;https://arxiv.org/pdf/2404.17571 主頁&#xff1a;https://mengtingchen.github.io/tunnel-try-on-page/ 一、摘要總結 隨著虛擬試衣技術的發展&#xff0c;消費者和時尚行業對于能夠在視頻中實現高質量虛擬試衣的需求日益增長。這項技術允許用戶在不實際穿…

目標檢測——印度車輛數據集

引言 親愛的讀者們&#xff0c;您是否在尋找某個特定的數據集&#xff0c;用于研究或項目實踐&#xff1f;歡迎您在評論區留言&#xff0c;或者通過公眾號私信告訴我&#xff0c;您想要的數據集的類型主題。小編會竭盡全力為您尋找&#xff0c;并在找到后第一時間與您分享。 …

弱監督語義分割學習筆記

目錄 partial cross entropy loss GitHub - LiheYoung/UniMatch: [CVPR 2023] Revisiting Weak-to-Strong Consistency in Semi-Supervised Semantic Segmentation partial cross entropy loss import torch import torch.nn.functional as Fdef partial_cross_entropy_loss…

區塊鏈中的APP與傳統APP的區別

一、技術 區塊鏈中的APP是基于區塊鏈技術開發的&#xff0c;而傳統APP則基于傳統的應用程序商店或網頁。區塊鏈中的APP利用區塊鏈技術的去中心化、數據不可篡改等特點&#xff0c;使得應用程序的開發和分發更加安全、透明和可信。與傳統APP相比&#xff0c;區塊鏈中的APP無需中…

如何實現嵌套路由

實現步驟 1. 新建子頁面 2. 在router/index.js中的父路由節點添加children數組 3. 在children中添加子路由 {path: /,name: home,component: HomeView,children: [ {path: /pageA,name: pageA,component: pageA},{path: /pageB,name: pageB,component: pageB}] }, 5.在父路…

Web安全:SQL注入之布爾盲注原理+步驟+實戰操作

「作者簡介」&#xff1a;2022年北京冬奧會網絡安全中國代表隊&#xff0c;CSDN Top100&#xff0c;就職奇安信多年&#xff0c;以實戰工作為基礎對安全知識體系進行總結與歸納&#xff0c;著作適用于快速入門的 《網絡安全自學教程》&#xff0c;內容涵蓋系統安全、信息收集等…

前端VUE基礎之創建腳手架

創建腳手架 第一步&#xff08;僅第一次執行&#xff09;&#xff1a;全局安裝vue/cli。 npm install -g vue/cli 到你要創建項目的目錄&#xff0c;然后使用命令創建項目 vue create xxxx 第三步&#xff1a;啟動項目 npm run serv 備注&#xff1a; 1. 如出現下載緩慢請…

PHP流程控制

PHP 流程控制主要是 if 和 switch 流程控制。 當您編寫代碼時&#xff0c;您常常需要為不同的判斷執行不同的動作。您可以在代碼中使用條件語句來完成此任務。 在 PHP 中&#xff0c;提供了下列條件語句&#xff1a; if 語句 - 在條件成立時執行代碼if...else 語句 - 在條件…

訪客管理系統對于校園安全的重要性

校園訪客辦理計劃是針對校園安全需求規劃的安全辦理體系&#xff0c;主要用于對校園外來人員的科學辦理。要做好校園安全作業&#xff0c;把風險分子拒之門外尤為要害。校園訪客辦理計劃實現訪客實名制&#xff0c;并結合公安網、黑名單功用&#xff0c;對風險人員進行提前預警…