成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

大數(shù)據(jù)
當(dāng)我們開始學(xué)習(xí)樹和圖的時(shí)候,這兩個(gè)數(shù)據(jù)結(jié)構(gòu)確實(shí)會(huì)讓人困惑,因?yàn)樗鼈兇鎯?chǔ)數(shù)據(jù)不是線性方式了。這兩種數(shù)據(jù)結(jié)構(gòu)都用特定的方式存儲(chǔ)數(shù)據(jù)。這篇文章幫助你更好的理解樹形數(shù)據(jù)結(jié)構(gòu)并幫你弄清楚你對(duì)它的疑問。

當(dāng)你剛開始學(xué)習(xí)編程的時(shí)候,將數(shù)組作為“主要數(shù)據(jù)結(jié)構(gòu)”來(lái)學(xué)習(xí)是很常見的。

最終,你也會(huì)學(xué)習(xí)到哈希表。如果你正在攻讀計(jì)算機(jī)科學(xué)學(xué)位,你肯定需要參加一門數(shù)據(jù)結(jié)構(gòu)的課程。在課上你將會(huì)學(xué)到鄰接鏈表、隊(duì)列和棧。這些數(shù)據(jù)結(jié)構(gòu)都被稱作是“線性”的,因?yàn)樗麄兌加羞壿嬌系钠瘘c(diǎn)和終點(diǎn)。

當(dāng)我們開始學(xué)習(xí)樹和圖的時(shí)候,這兩個(gè)數(shù)據(jù)結(jié)構(gòu)確實(shí)會(huì)讓人困惑,因?yàn)樗鼈兇鎯?chǔ)數(shù)據(jù)不是線性方式了。這兩種數(shù)據(jù)結(jié)構(gòu)都用特定的方式存儲(chǔ)數(shù)據(jù)。

這篇文章幫助你更好的理解樹形數(shù)據(jù)結(jié)構(gòu)并幫你弄清楚你對(duì)它的疑問。

[[209900]]

本篇文章我們將會(huì)學(xué)習(xí)到:

  • 樹是什么?
  • 樹的例子
  • 樹的術(shù)語(yǔ)及其工作原理
  • 如何用代碼實(shí)現(xiàn)樹形結(jié)構(gòu)

讓我們開始學(xué)習(xí)之旅吧。:)

定義

當(dāng)開始編程時(shí),人們更容易理解線性數(shù)據(jù)結(jié)構(gòu),而不是像樹和圖這樣的數(shù)據(jù)結(jié)構(gòu)。

樹是眾所周知的非線性數(shù)據(jù)結(jié)構(gòu)。它們不以線性方式存儲(chǔ)數(shù)據(jù),而是按層次組織數(shù)據(jù)。

讓我們舉個(gè)現(xiàn)實(shí)生活中的例子

當(dāng)我說(shuō)層次方式意味著什么?

想象一個(gè)有所有輩分關(guān)系的家譜:祖父母、父母、子女、兄弟姐妹們等等。我們通常按層次結(jié)構(gòu)組織家譜。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

上面的圖是我的家譜。Tossico 、Akikazu 、Hitomi 和 Takemi 是我的祖父母。

Toshiaki 和 Juliana 是我的父母。

TK 、Yuji 、Bruno 和 Kaio 是我父母的孩子(我和我的兄弟們)。

另一個(gè)層次結(jié)構(gòu)的例子是企業(yè)的組織結(jié)構(gòu)。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

在 HTML 中,文檔對(duì)象模型(DOM)是樹形結(jié)構(gòu)的。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

HTML 標(biāo)簽包含其他的標(biāo)簽。我們有一個(gè) head 標(biāo)簽和 body 標(biāo)簽。這些標(biāo)簽包含特點(diǎn)的元素。head 標(biāo)簽中有 meta 和 title 標(biāo)簽。body 標(biāo)簽中有在用戶界面展示的標(biāo)簽,如 h1 、a 、li 等等。

術(shù)語(yǔ)定義

樹是被稱為節(jié)點(diǎn)的元素的集合。節(jié)點(diǎn)通過邊連接。每個(gè)節(jié)點(diǎn)都有一個(gè)值或數(shù)據(jù)。每個(gè)節(jié)點(diǎn)也可能有或者沒有子節(jié)點(diǎn)。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

樹的首節(jié)點(diǎn)是這個(gè)樹的根(root)節(jié)點(diǎn)。如果這個(gè)根節(jié)點(diǎn)連接了另一個(gè)節(jié)點(diǎn),那么,另一個(gè)節(jié)點(diǎn)稱作這個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

所有樹節(jié)點(diǎn)都由邊連接。它是樹的重要組成部分, 因?yàn)樗芾砉?jié)點(diǎn)之間的關(guān)系。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

葉節(jié)點(diǎn)是樹上的***一個(gè)節(jié)點(diǎn)。他們是沒有子節(jié)點(diǎn)的節(jié)點(diǎn)。數(shù)據(jù)結(jié)構(gòu)中的樹像真正的樹, 有根, 樹枝, 和葉子。

要理解的其他重要概念是樹的高度和深度。

  • 樹的高度是葉節(jié)點(diǎn)的最長(zhǎng)路徑的長(zhǎng)度。
  • 節(jié)點(diǎn)的深度是從其到根的路徑的長(zhǎng)度。

術(shù)語(yǔ)摘要

  • 根是樹的最頂端結(jié)點(diǎn)。
  • 邊是兩個(gè)結(jié)點(diǎn)之間的連接。
  • 子結(jié)點(diǎn)是具有父節(jié)點(diǎn)的結(jié)點(diǎn)。
  • 父結(jié)點(diǎn)是與子節(jié)點(diǎn)有連接的結(jié)點(diǎn)。
  • 葉子結(jié)點(diǎn)是樹中沒有子結(jié)點(diǎn)的結(jié)點(diǎn)。
  • 高度是 樹 到葉子結(jié)點(diǎn)的長(zhǎng)度。
  • 深度是 結(jié)點(diǎn) 到根結(jié)點(diǎn)的長(zhǎng)度。

二叉樹

現(xiàn)在我們來(lái)討論一個(gè)特殊的樹類型。我們把它叫作二叉樹。

“在計(jì)算機(jī)科學(xué)領(lǐng)域,二叉樹是一種樹形數(shù)據(jù)結(jié)構(gòu),它的每個(gè)節(jié)點(diǎn)最多有兩個(gè)孩子,被叫作左孩子和右孩”

我們來(lái)看一個(gè)二叉樹的例子。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

我們來(lái)寫一個(gè)二叉樹

在實(shí)現(xiàn)一個(gè)二叉樹時(shí),我們首先要注意的是,二叉樹是節(jié)點(diǎn)的集合。每一個(gè)節(jié)點(diǎn)有三個(gè)屬性:值(value), 左孩子( left_child) ,以及右孩子( right_child)。

那么我們?cè)趺床拍軐?shí)現(xiàn)一個(gè)有這三個(gè)屬性的簡(jiǎn)單二叉樹呢?

 

  1. class BinaryTree: 
  2.     def __init__(self, value): 
  3.         self.value = value 
  4.         self.left_child = None 
  5.         self.right_child = None 

好,這就是我們的二叉樹類。

當(dāng)我們實(shí)例化一個(gè)對(duì)象時(shí),我們把值(節(jié)點(diǎn)的相關(guān)數(shù)據(jù))作為參數(shù)傳遞給類。看上面類的左孩子和右孩子。兩個(gè)都被賦值為None。

為什么?

因?yàn)楫?dāng)我們創(chuàng)建節(jié)點(diǎn)時(shí),它還沒有孩子,只有節(jié)點(diǎn)數(shù)據(jù)。

測(cè)試下代碼。

 

  1. tree = BinaryTree('a'
  2. print(tree.value) # a 
  3. print(tree.left_child) # None 
  4. print(tree.right_child) # None 

好了。

我們可以將字符串'a'作為值傳給二叉樹節(jié)點(diǎn)。如果將值、左孩子、右孩子輸出的話,我們就可以看到這個(gè)值了。

下面開始插入部分的操作。那么我們需要做些什么工作呢?

有兩個(gè)要求:

  • 如果當(dāng)前的節(jié)點(diǎn)沒有左孩子,我們就創(chuàng)建一個(gè)新節(jié)點(diǎn),然后將其設(shè)置為當(dāng)前節(jié)點(diǎn)的左孩子。
  • 如果已經(jīng)有了左孩子,我們就創(chuàng)建一個(gè)新節(jié)點(diǎn),并將其放在當(dāng)前左孩子節(jié)點(diǎn)的位置。然后再將左孩子節(jié)點(diǎn)置為新節(jié)點(diǎn)的左孩子。

畫出來(lái)就像下面這樣。:)

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

下面是插入操作的代碼:

 

  1. def insert_left(self, value): 
  2.     if self.left_child == None: 
  3.         self.left_child = BinaryTree(value) 
  4.     else
  5.         new_node = BinaryTree(value) 
  6.         new_node.left_child = self.left_child 
  7.         self.left_child = new_node 

再次強(qiáng)調(diào),如果當(dāng)前節(jié)點(diǎn)沒有左孩子,我們就創(chuàng)建一個(gè)新節(jié)點(diǎn),并將其置為當(dāng)前節(jié)點(diǎn)的左孩子。否則,就將新節(jié)點(diǎn)放在左孩子的位置,再將原左孩子置為新節(jié)點(diǎn)的左孩子。

同樣,我們編寫插入右孩子的代碼。

 

  1. def insert_right(self, value): 
  2.     if self.right_child == None: 
  3.         self.right_child = BinaryTree(value) 
  4.     else
  5.         new_node = BinaryTree(value) 
  6.         new_node.right_child = self.right_child 
  7.         self.right_child = new_node 

好了。:)

但是這還不算完成。我們得測(cè)試一下。

我們來(lái)構(gòu)造一個(gè)像下面這樣的樹:

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

總結(jié)分析下這棵樹:

  • 有一個(gè)根節(jié)點(diǎn)
  • b是左孩子
  • c是右孩子
  • b的右孩子是d(b沒有左孩子)
  • c的左孩子是e
  • c的右孩子是f
  • e和f都沒有孩子

下面是整棵樹的實(shí)現(xiàn)代碼:

 

  1. a_node = BinaryTree('a'
  2. a_node.insert_left('b'
  3. a_node.insert_right('c'
  4.  
  5. b_node = a_node.left_child 
  6. b_node.insert_right('d'
  7.  
  8. c_node = a_node.right_child 
  9. c_node.insert_left('e'
  10. c_node.insert_right('f'
  11.  
  12. d_node = b_node.right_child 
  13. e_node = c_node.left_child 
  14. f_node = c_node.right_child 
  15.  
  16. print(a_node.value) # a 
  17. print(b_node.value) # b 
  18. print(c_node.value) # c 
  19. print(d_node.value) # d 
  20. print(e_node.value) # e 
  21. print(f_node.value) # f 

好,插入結(jié)束。

現(xiàn)在,我們來(lái)思考一下樹的遍歷。

遍歷樹有兩種選擇:深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)。

  • DFS是用來(lái)遍歷或搜索樹數(shù)據(jù)結(jié)構(gòu)的算法。從根節(jié)點(diǎn)開始,在回溯之前沿著每一個(gè)分支盡可能遠(yuǎn)的探索。
  • BFS是用來(lái)遍歷或搜索樹數(shù)據(jù)結(jié)構(gòu)的算法。從根節(jié)點(diǎn)開始,在探索下一層鄰居節(jié)點(diǎn)前,首先探索同一層的鄰居節(jié)點(diǎn)。

下面,我們來(lái)深入了解每一種遍歷算法。

深度優(yōu)先搜索(Depth-First Search,DFS)

DFS 在 回溯 和搜索其他路徑之前找到一條到葉節(jié)點(diǎn)的路徑。讓我們看看這種類型的遍歷的示例。

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

此算法的結(jié)果是 1–2–3–4–5–6–7 。

為什么呢?

讓我們分解下。

  1. 從根節(jié)點(diǎn)(1)開始。輸出之。
  2. 進(jìn)入左孩子(2)。輸出之。
  3. 然后進(jìn)入左孩子(3)。輸出之。(此節(jié)點(diǎn)無(wú)子孩子)
  4. 回溯,并進(jìn)入右孩子(4)。輸出之。(此節(jié)點(diǎn)無(wú)子孩子)
  5. 回溯到根節(jié)點(diǎn),然后進(jìn)入其右孩子(5)。輸出之。
  6. 進(jìn)入左孩子(6)。輸出之。(此節(jié)點(diǎn)無(wú)子孩子)
  7. 回溯,并進(jìn)入右孩子(7)。輸出之。(此節(jié)點(diǎn)無(wú)子孩子)
  8. 完成。

當(dāng)我們深入到葉節(jié)點(diǎn)時(shí)回溯,這就被稱為 DFS 算法。

既然我們對(duì)這種遍歷算法已經(jīng)熟悉了,我們將討論下 DFS 的類型:前序、中序和后序。

前序遍歷

這和我們?cè)谏鲜鍪纠械淖鞣ɑ绢愃啤?/p>

  1. 輸出節(jié)點(diǎn)的值。
  2. 進(jìn)入其左孩子并輸出之。當(dāng)且僅當(dāng)它擁有左孩子。
  3. 進(jìn)入右孩子并輸出之。當(dāng)且僅當(dāng)它擁有右孩子。

 

  1. def pre_order(self): 
  2.     print(self.value) 
  3.  
  4.     if self.left_child: 
  5.         self.left_child.pre_order() 
  6.  
  7.     if self.right_child: 
  8.         self.right_child.pre_order() 

中序遍歷

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

示例中此樹的中序算法的結(jié)果是3–2–4–1–6–5–7。

左孩子優(yōu)先,之后是中間,***是右孩子。

現(xiàn)在讓我們編碼實(shí)現(xiàn)之。

 

  1. def in_order(self): 
  2.     if self.left_child: 
  3.         self.left_child.in_order() 
  4.  
  5.     print(self.value) 
  6.  
  7.     if self.right_child: 
  8.         self.right_child.in_order() 
  1. 進(jìn)入左孩子并輸出之。當(dāng)且僅當(dāng)它有左孩子。
  2. 輸出節(jié)點(diǎn)的值。
  3. 進(jìn)入右孩子并輸出之。當(dāng)且僅當(dāng)它有右孩子。

后序遍歷

數(shù)據(jù)結(jié)構(gòu)中你需要知道的關(guān)于樹的一切

以此樹為例的后序算法的結(jié)果為 3–4–2–6–7–5–1 。

左孩子優(yōu)先,之后是右孩子,中間的***。

讓我們編碼實(shí)現(xiàn)吧。

 

  1. def post_order(self): 
  2.     if self.left_child: 
  3.         self.left_child.post_order() 
  4.  
  5.     if self.right_child: 
  6.         self.right_child.post_order() 
  7.  
  8.     print(self.value) 
  1. 進(jìn)入左孩子并輸出之。這當(dāng)且僅當(dāng)它擁有左孩子。
  2. 進(jìn)入右孩子并輸出之。這當(dāng)且僅當(dāng)它擁有右孩子。
  3. 輸出節(jié)點(diǎn)的值。
責(zé)任編輯:未麗燕 來(lái)源: 開源中國(guó)翻譯文章
相關(guān)推薦

2023-02-10 08:44:05

KafkaLinkedIn模式

2022-09-01 15:26:45

物聯(lián)網(wǎng)人工智能傳感器

2022-04-24 09:00:00

滲透測(cè)試安全數(shù)字時(shí)代

2022-12-30 11:24:21

2022-07-15 14:58:26

數(shù)據(jù)分析人工智能IT

2018-06-15 23:00:56

2022-08-27 12:15:51

Linux Mint操作系統(tǒng)

2017-04-29 09:00:14

Linux程序進(jìn)程

2019-05-22 15:10:43

2022-11-28 00:07:47

2020-12-22 11:04:05

人工智能AI機(jī)器學(xué)習(xí)

2023-02-07 08:26:23

LinuxInode

2016-02-29 09:37:44

5G

2022-12-29 11:42:27

2023-10-12 07:06:32

2020-11-17 10:38:40

云計(jì)算工具技術(shù)

2023-10-12 09:42:44

2023-02-27 15:47:31

2021-12-29 14:24:12

物聯(lián)網(wǎng)IoT5G

2022-07-06 10:07:21

物聯(lián)網(wǎng)IoT
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 成人免费观看视频 | 国产精品一区二区三区在线 | 最新免费黄色网址 | 搞av.com| 国产a视频 | 精品国产乱码久久久久久88av | 日韩在线资源 | 欧美视频1区 | 欧美一级欧美一级在线播放 | 亚洲成人福利在线观看 | 91成人免费 | 一区福利视频 | 国产一区二区三区四区 | 在线免费看黄 | 欧美国产日韩在线 | 亚洲精品小视频在线观看 | 国产中文字幕网 | 亚洲黄色在线免费观看 | 国产亚洲精品综合一区 | 国产做a爱片久久毛片 | 亚洲欧美日韩一区二区 | 国产成人在线播放 | 日韩欧美在线免费观看视频 | 精品国产一区二区在线 | 日韩精品专区在线影院重磅 | 中文字幕日韩欧美一区二区三区 | 爱综合 | 天天影视网天天综合色在线播放 | 免费精品久久久久久中文字幕 | 成人午夜在线观看 | 中文日本在线 | 黄色在线免费看 | 精品久久香蕉国产线看观看亚洲 | 99reav | 免费黄色网址视频 | 中文av在线播放 | 国产高清精品一区二区三区 | 欧美日韩精品在线免费观看 | 午夜av电影院 | 日韩在线观看一区二区三区 | 午夜视频一区 |