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

詳解數據結構二叉樹及其代碼實現

開發 前端
樹是一種非常重要的非線性結構,本身具有遞歸的性質(在其后的編程中體現的淋漓盡致)。

 樹

樹是一種非常重要的非線性結構,本身具有遞歸的性質(在其后的編程中體現的淋漓盡致)。


看下圖,A 節點就是 B 節點的父節點,B 節點是 A 節點的子節點。B、C、D 這三個節點的父節點是同一個節點A,沒有父節點的叫做根節點,也就是 E 。

 

沒有子節點的節點叫作葉子節點或者葉節點,圖中的G,H,I,J,K,L

關于“樹”,還有三個比較相似的概念:高度(Height)、深度(Depth),層(level)


二叉樹(binary Tree)

二叉樹是n(n>=0)個結點的有限集合,該集合或者為空集(稱為空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱為根結點的左子樹和右子樹組成。


上圖中,編號1是普通二叉樹,編號2又是滿二叉樹,編號2又是完全二叉樹。

滿二叉樹:在一棵二叉樹中。如果所有分支結點都存在左子樹和右子樹,并且所有葉子都在同一層上,這樣的二叉樹稱為滿二叉樹。

滿二叉樹的特點有:

  • 葉子只能出現在最下一層。出現在其它層就不可能達成平衡。
  • 非葉子結點的度一定是2。
  • 在同樣深度的二叉樹中,滿二叉樹的結點個數最多,葉子數最多。

編號3是完全二叉樹

「對一顆具有n個結點的二叉樹按層編號,如果編號為i(1<=i<=n)的結點與同樣深度的滿二叉樹中編號為i的結點在二叉樹中位置完全相同,則這棵二叉樹稱為完全二叉樹。」

就是保證葉子節點的上面層都要達到最大,最低下兩層,最后一層的葉子節點都靠左排列


二叉樹具備以下數學性質:

在二叉樹的第i層上至多有2(i-1)個結點(i>0)

深度為k的二叉樹至多有2K-1個結點(k>0)

對于任意一棵二叉樹,如果其葉結點數為N0,而度數為2的結點總數為N2,則N0=N2+1;

具有n個結點的完全二叉樹的深度必為log2(n+1)

二叉樹的遍歷和節點的刪除

二叉樹的遍歷是指從二叉樹的根結點出發,按照某種次序依次訪問二叉樹中的所有結點,使得每個結點被訪問一次,且僅被訪問一次。

  • 中序遍歷:先左子樹,再根節點,最后右子樹
  • 前序遍歷:先根節點,再左子樹,最后右子樹
  • 后序遍歷:先左子樹,再右子樹,最后根節點。

前序遍歷通俗的說就是從二叉樹的根結點出發,當第一次到達結點時就輸出結點數據,按照先向左在向右的方向訪問。

中序遍歷就是從二叉樹的根結點出發,當第二次到達結點時就輸出結點數據,按照先向左在向右的方向訪問。

后序遍歷就是從二叉樹的根結點出發,當第三次到達結點時就輸出結點數據,按照先向左在向右的方向訪問。


刪除共有三種情況

  • 被刪除的節點是葉子節點,這時候只要把這個節點刪除,再把指向這個節點的父節點指針置為空就行
  • 被刪除的節點有左子樹,或者有右子樹,而且只有其中一個,那么只要把當前刪除節點的父節點指向被刪除節點的左子樹或者右子樹就行。
  • 如果要刪除的節點有兩個子節點,需要找到這個節點的右子樹的最小節點,把它替換到要刪除的節點上,然后再刪除掉這個最小節點,因為最小節點肯定沒有左子節點

 

代碼具體實現二叉樹

上面就是二叉樹全部內容,下面用Pytho代碼具體實現二叉樹。

按下來就是編程實現了,請動手自己實現一把。

先實現一個 node 節點類:

  1. class Node(object): 
  2.     def __init__(self, item): 
  3.         self.item = item 
  4.         self.left = None 
  5.         self.right = None 
  6.  
  7.     def __str__(self): 
  8.         return str(self.item) 

這里的 __str__ 方法是為了方便打印。在 print 一個 Node 類時會打印__str__的返回值,例如:print(Node(5)) 就會打印出字符串 5 。

實現一個二叉樹類:

  1. class Tree(object): 
  2.     def __init__(self): 
  3.         # 根節點定義為 root 永不刪除,做為哨兵使用。 
  4.         self.root = Node('root'
  5.     # 添加節點操作 
  6.     def add(self, item): 
  7.         node = Node(item) 
  8.         if self.root is None: 
  9.             self.root = node 
  10.         else
  11.             q = [self.root] 
  12.             while True
  13.                 pop_node = q.pop(0) 
  14.                 if pop_node.left is None: 
  15.                     pop_node.left = node 
  16.                     return 
  17.                 elif pop_node.right is None: 
  18.                     pop_node.right = node 
  19.                     return 
  20.                 else
  21.                     q.append(pop_node.left
  22.                     q.append(pop_node.right
  23.  
  24.     def get_parent(self, item): 
  25.         ''
  26.         找到 Item 的父節點 
  27.         ''
  28.         if self.root.item == item: 
  29.             return None  # 根節點沒有父節點 
  30.         tmp = [self.root] 
  31.         while tmp: 
  32.             pop_node = tmp.pop(0) 
  33.             if pop_node.left and pop_node.left.item == item: 
  34.                 return pop_node 
  35.             if pop_node.right and pop_node.right.item == item: 
  36.                 return pop_node 
  37.             if pop_node.left is not None: 
  38.                 tmp.append(pop_node.left
  39.             if pop_node.right is not None: 
  40.                 tmp.append(pop_node.right
  41.         return None 
  42.  
  43.     def delete(self, item): 
  44.         ''
  45.         從二叉樹中刪除一個元素 
  46.         先獲取 待刪除節點 item 的父節點 
  47.         如果父節點不為空, 
  48.             判斷 item 的左右子樹 
  49.             如果左子樹為空,那么判斷 item 是父節點的左孩子,還是右孩子,如果是左孩子,將父節點的左指針指向 item 的右子樹,反之將父節點的右指針指向 item 的右子樹 
  50.             如果右子樹為空,那么判斷 item 是父節點的左孩子,還是右孩子,如果是左孩子,將父節點的左指針指向 item 的左子樹,反之將父節點的右指針指向 item 的左子樹 
  51.             如果左右子樹均不為空,尋找右子樹中的最左葉子節點 x ,將 x 替代要刪除的節點。 
  52.         刪除成功,返回 True 
  53.         刪除失敗, 返回 False 
  54.  
  55.         ''
  56.         if self.root is None:  # 如果根為空,就什么也不做 
  57.             return False 
  58.  
  59.         parent = self.get_parent(item) 
  60.         if parent: 
  61.             del_node = parent.left if parent.left.item == item else parent.right  # 待刪除節點 
  62.             if del_node.left is None: 
  63.                 if parent.left.item == item: 
  64.                     parent.left = del_node.right 
  65.                 else
  66.                     parent.right = del_node.right 
  67.                 del del_node 
  68.                 return True 
  69.             elif del_node.right is None: 
  70.                 if parent.left.item == item: 
  71.                     parent.left = del_node.left 
  72.                 else
  73.                     parent.right = del_node.left 
  74.                 del del_node 
  75.                 return True 
  76.             else:  # 左右子樹都不為空 
  77.                 tmp_pre = del_node 
  78.                 tmp_next = del_node.right 
  79.                 if tmp_next.left is None: 
  80.                     # 替代 
  81.                     tmp_pre.right = tmp_next.right 
  82.                     tmp_next.left = del_node.left 
  83.                     tmp_next.right = del_node.right 
  84.  
  85.                 else
  86.                     while tmp_next.left:  # 讓tmp指向右子樹的最后一個葉子 
  87.                         tmp_pre = tmp_next 
  88.                         tmp_next = tmp_next.left 
  89.                     # 替代 
  90.                     tmp_pre.left = tmp_next.right 
  91.                     tmp_next.left = del_node.left 
  92.                     tmp_next.right = del_node.right 
  93.                 if parent.left.item == item: 
  94.                     parent.left = tmp_next 
  95.                 else
  96.                     parent.right = tmp_next 
  97.                 del del_node 
  98.                 return True 
  99.         else
  100.             return False 
  101.  
  102.     def traverse(self):  # 層次遍歷 
  103.         if self.root is None: 
  104.             return None 
  105.         q = [self.root] 
  106.         res = [self.root.item] 
  107.         while q != []: 
  108.             pop_node = q.pop(0) 
  109.             if pop_node.left is not None: 
  110.                 q.append(pop_node.left
  111.                 res.append(pop_node.left.item) 
  112.  
  113.             if pop_node.right is not None: 
  114.                 q.append(pop_node.right
  115.                 res.append(pop_node.right.item) 
  116.         return res 
  117.  
  118.     def preorder(self, root):  # 先序遍歷 
  119.         if root is None: 
  120.             return [] 
  121.         result = [root.item] 
  122.         left_item = self.preorder(root.left
  123.         right_item = self.preorder(root.right
  124.         return result + left_item + right_item 
  125.  
  126.     def inorder(self, root):  # 中序遍歷 
  127.         if root is None: 
  128.             return [] 
  129.         result = [root.item] 
  130.         left_item = self.inorder(root.left
  131.         right_item = self.inorder(root.right
  132.         return left_item + result + right_item 
  133.  
  134.     def postorder(self, root):  # 后序遍歷 
  135.         if root is None: 
  136.             return [] 
  137.         result = [root.item] 
  138.         left_item = self.postorder(root.left
  139.         right_item = self.postorder(root.right
  140.         return left_item + right_item + result 

運行測試:

  1. if __name__ == '__main__'
  2.     t = Tree() 
  3.     for i in range(10): 
  4.         t.add(i) 
  5.     print('層序遍歷:', t.traverse()) 
  6.     print('先序遍歷:', t.preorder(t.root)) 
  7.     print('中序遍歷:', t.inorder(t.root)) 
  8.     print('后序遍歷:', t.postorder(t.root)) 
  9.  
  10.     for i in range(10): 
  11.         print(i, " 的父親", t.get_parent(i)) 
  12.  
  13.     for i in range(0, 15, 3): 
  14.         print(f"刪除 {i}"'成功' if t.delete(i) else '失敗'
  15.         print('層序遍歷:', t.traverse()) 
  16.         print('先序遍歷:', t.preorder(t.root)) 
  17.         print('中序遍歷:', t.inorder(t.root)) 
  18.         print('后序遍歷:', t.postorder(t.root)) 

執行結果如下:

  1. 層序遍歷: ['root', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
  2. 先序遍歷: ['root', 0, 2, 6, 7, 3, 8, 9, 1, 4, 5] 
  3. 中序遍歷: [6, 2, 7, 0, 8, 3, 9, 'root', 4, 1, 5] 
  4. 后序遍歷: [6, 7, 2, 8, 9, 3, 0, 4, 5, 1, 'root'
  5. 0  的父親 root 
  6. 1  的父親 root 
  7. 2  的父親 0 
  8. 3  的父親 0 
  9. 4  的父親 1 
  10. 5  的父親 1 
  11. 6  的父親 2 
  12. 7  的父親 2 
  13. 8  的父親 3 
  14. 9  的父親 3 
  15. 刪除 0 成功 
  16. 層序遍歷: ['root', 8, 1, 2, 3, 4, 5, 6, 7, 9] 
  17. 先序遍歷: ['root', 8, 2, 6, 7, 3, 9, 1, 4, 5] 
  18. 中序遍歷: [6, 2, 7, 8, 3, 9, 'root', 4, 1, 5] 
  19. 后序遍歷: [6, 7, 2, 9, 3, 8, 4, 5, 1, 'root'
  20. 刪除 3 成功 
  21. 層序遍歷: ['root', 8, 1, 2, 9, 4, 5, 6, 7] 
  22. 先序遍歷: ['root', 8, 2, 6, 7, 9, 1, 4, 5] 
  23. 中序遍歷: [6, 2, 7, 8, 9, 'root', 4, 1, 5] 
  24. 后序遍歷: [6, 7, 2, 9, 8, 4, 5, 1, 'root'
  25. 刪除 6 成功 
  26. 層序遍歷: ['root', 8, 1, 2, 9, 4, 5, 7] 
  27. 先序遍歷: ['root', 8, 2, 7, 9, 1, 4, 5] 
  28. 中序遍歷: [2, 7, 8, 9, 'root', 4, 1, 5] 
  29. 后序遍歷: [7, 2, 9, 8, 4, 5, 1, 'root'
  30. 刪除 9 成功 
  31. 層序遍歷: ['root', 8, 1, 2, 4, 5, 7] 
  32. 先序遍歷: ['root', 8, 2, 7, 1, 4, 5] 
  33. 中序遍歷: [2, 7, 8, 'root', 4, 1, 5] 
  34. 后序遍歷: [7, 2, 8, 4, 5, 1, 'root'
  35. 刪除 12 失敗 
  36. 層序遍歷: ['root', 8, 1, 2, 4, 5, 7] 
  37. 先序遍歷: ['root', 8, 2, 7, 1, 4, 5] 
  38. 中序遍歷: [2, 7, 8, 'root', 4, 1, 5] 
  39. 后序遍歷: [7, 2, 8, 4, 5, 1, 'root'

Binarytree是一個Python庫,它通過一個簡單的API生成二叉樹,可以進行檢查和操作。Github:https://github.com/joowani/binarytree/releases。

本文已收錄 GitHub  https://github.com/MaoliRUNsen/runsenlearnpy100

 

責任編輯:姜華 來源: Python之王
相關推薦

2021-04-20 08:37:14

數據結構二叉樹

2021-04-19 07:47:42

數據結構二叉樹Tree

2021-04-28 20:12:27

數據結構創建

2013-01-30 10:34:02

數據結構

2020-11-02 09:15:47

算法與數據結構

2020-04-27 07:05:58

二叉樹左子樹右子樹

2021-04-01 10:34:18

Java編程數據結構算法

2021-03-19 10:25:12

Java數據結構算法

2020-09-23 18:25:40

算法二叉樹多叉樹

2021-03-22 09:00:22

Java數據結構算法

2018-03-15 08:31:57

二叉樹存儲結構

2021-10-12 09:25:11

二叉樹樹形結構

2019-08-22 09:22:44

數據結構二叉搜索樹

2013-07-15 16:35:55

二叉樹迭代器

2021-03-17 08:19:22

二叉樹LeetCode

2021-09-29 10:19:00

算法平衡二叉樹

2009-08-11 13:29:57

C#二叉樹遍歷

2020-12-22 08:56:51

JavaScript數據結構前端

2021-05-06 17:46:30

二叉樹數據結構

2022-10-26 23:58:02

二叉樹數組算法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩精品亚洲 | 国产这里只有精品 | www.久久99 | 日日骚视频 | 一级黄色在线 | 免费看淫片 | 亚洲欧美aⅴ | 欧美精品在线观看 | 综合色站导航 | 亚洲精品视频一区二区三区 | 国产精品美女视频 | 亚洲精选久久 | 国产免费一级一级 | 综合久久一区 | 久久精品国产一区 | 亚洲国产成人精品在线 | 久久久久久毛片免费观看 | 久久久久久国产精品免费免费狐狸 | 性做久久久久久免费观看欧美 | 欧美精品一区二区三区在线 | 天天综合网永久 | 天天草狠狠干 | 成人av观看 | 伊人99 | 国产中文字幕网 | 日本免费小视频 | 天天干天天谢 | 在线国产视频 | 狠狠撸在线视频 | 国产精品久久久久久婷婷天堂 | 精品中文在线 | 91精品久久久久久久久久 | 久草在线在线精品观看 | 国外成人在线视频 | 亚洲国产免费 | 日韩免费网站 | 亚洲成人黄色 | 午夜综合 | 欧美性jizz18性欧美 | 免费在线观看成人 | 国产亚洲精品综合一区 |