資料結構-二叉樹、堆、圖

sleeeeeping發表於2024-07-28

一、線索二叉樹

  • 規律:在有n個節點的鏈式二叉樹中必定存在 n+1 個空指標
  • 鏈式二叉樹中有很多的空指標,可以讓這些空指標指向前一個節點\後一個節點,從而在有序遍歷(中序遍歷)二叉樹時,不需要使用遞迴而透過迴圈即可以完成,並且效率要比遞迴快得多
  • 一定是搜尋二叉樹

線索二叉樹的結構

typedef struct TreeNode {
    int data;	//	資料域
    struct TreeNode* left;
    bool lflag;		//	左子樹是否是線索  為真時,左子樹是線索 指向前一個節點
    struct TreeNode* right;
    bool rflag;		//	右子樹是否是線索  為真時,右子樹是線索 指向下一個節點
} TreeNode;

構建線索二叉樹

  • 首先需要有一顆搜尋二叉樹,然後透過中序遍歷並生成線索,透過檢查右子樹是否為空來決定是否生成線索,讓右子樹指向下一個節點。
  • 當構成線索二叉樹後 ,可以透過迴圈遍歷的方式有序遍歷二叉樹,不需要中序遞迴遍歷也可以

程式碼實現

二、選擇樹

  • 是一種完全二叉樹,把待比較的資料儲存在最後一層,根節點的值是左右子樹中其中一個,是它們的最大值或最小值,選擇樹的功能是快速地找出最大值或最小值

三、堆

堆結構介紹

​ 大頂堆(大根堆):根節點的值比左右子樹都大,同時左右子樹都滿足該規則

​ 小頂堆(小根堆):根節點的值比左右子樹都小,同時左右子樹都滿足該規則

​ 堆結構是一種特殊的完全二叉樹,它與堆記憶體是兩種概念

​ 堆結構的根節點一定是整棵樹中的最大值、最小值

堆結構如何儲存:

​ 首先堆結構是一種完全二叉樹,並且需要在使用的時候頻繁地找雙親節點進行比較,所以鏈式不好找雙親節點,因此堆結構非常適合用順序儲存,透過二叉樹性質5來實現找雙親:

性質5:

​ 有一個n個結點的完全二叉樹,結點按照從上到下從左到右的順序排序為1~n。

​ 1、i > 1時,i/2就是它的雙親結點。

​ 2、i*2是i的左子樹,當i*2>n時,則i沒有左子樹。

​ 3、2*i+1是i的右子樹,2*i+1>n時,則i沒有右子樹

堆排序

  • 藉助堆結構,先把待排序陣列先調整成大頂堆或者小頂堆結構,然後堆頂與末尾元素交換,從堆頂到末尾元素的前一個元素之間重新調整成堆結構,重複該步驟,最後當堆中只剩一個元素時,待排序陣列就有序了。
  • 可以迴圈實現、也可以遞迴實現
  • 堆結構還是優先佇列的底層邏輯

程式碼實現

平衡二叉樹(AVL樹)

  • 前提一定是搜尋二叉樹,對於根節點的左右子樹的高度差不能超過1,並且所有子樹都要循序這個要求
  • 如果一個搜尋二叉樹呈現或接近單支狀,它的查詢效率很低,很接近連結串列,因此如果能讓它平衡時,查詢效率最高
  • 由於節點的位置要受到相互之間值的影響,並且在往平衡二叉樹中新增節點或者刪除節點前,二叉樹本身是平衡的,所以只可能在最後操作的節點附近不滿足平衡條件,因此需要在該過程中對該節點進行判斷並調整。
  • 因此一棵平衡二叉樹因為新增操作導致不平衡的原因,總結就四種:
第一種:
			x								y
		  /   \							 /     \	
		 y    t1                        z       x
	   /   \                          /   \   /   \
      z    t2                        t3  t4   t2  t1
     / \
    t3 t4              以y為軸 右旋轉
    
第二種:
		   x						     y
		 /   \						   /   \
		t1    y                       x     z
		    /   \                    / \   / \
		   t2    z                  t1 t2 t3 t4
		        / \
		       t3  t4  以y為軸 左旋轉
		      
		      
第三種:
			x		   		x			     z
		  /   \			   / \		       /   \
		 y    t1          z  t1           y     x 
	   /   \             / \            /  \   /  \
      t2    z           y  t4          t2  t3 t4  t1   
           / \         / \ 
          t3 t4       t2 t3    
          先以z為軸左旋轉			再以z為軸右旋轉 達到平衡
          
第四種:
			x		   		x			     z
		  /   \			   / \		       /   \
		 t1    y          t1  z           x     y 
	         /   \           / \         /  \  /  \
            z    t2         t3  y       t1  t3 t4 t2   
           / \                 / \ 
          t3 t4               t4 t2    
          先以z為軸右旋轉			再以z為軸左旋轉 達到平衡

刪除節點

  • 待刪除的節點是葉子節點,直接刪除
  • 待刪除節點的左子樹或者右子樹為空,則使用非空節點替換
  • 待刪除節點左右子樹非空,則根據左右子樹的高度,選擇高的一邊子樹,如果是左子樹高,選擇左子樹中的最大節點賦值給待刪除節點,然後再左子樹中繼續刪除該最大節點,相當於繼續處理情況1或情況2;如果是右子樹高,則在右子樹選擇最小值節點繼續同樣處理。
  • 刪除後可能導致不平衡,需要重新調整平衡

平衡二叉樹的優點:

​ 避免了二叉搜尋樹呈現單支狀,讓其能以最佳的效率進行查詢操作 O(log2n)

平衡二叉樹的缺點:

​ 在插入、刪除操作時,為了達到平衡需要進行大量的左旋、右旋操作、計算高度,所以此時操作速度慢

​ 因此AVL樹適合在資料量大並且資料量比較穩定,沒有太多的插入、刪除操作,適合大量的查詢操作。

程式碼實現

紅黑樹

  • 是一種自平衡的有序二叉樹,不是根據樹的高來調整平衡、而是樹節點的顏色來調整

紅黑樹的特性:
(1)每個節點或者是黑色,或者是紅色。
(2)根節點是黑色。
(3)每個葉子節點(NIL)是黑色。 [注意:這裡葉子節點,是指為空(NIL或NULL)的葉子節點!]
(4)如果一個節點是紅色的,則它的子節點必須是黑色的。
(5)從一個節點到該節點的子孫節點的所有路徑上包含相同數目的黑節點。

紅黑樹的優點:

​ 插入、刪除操作的效率比AVL高

缺點:

​ 沒有AVL那麼均勻,查詢效率略低於AVL樹,但是因為性質5決定了不至於太差,綜合而言,綜合效能優秀,所以應用場景很多

哈夫曼樹

相關基礎概念

路徑長度:從一個節點到另一個節點之間的路徑條數目

​ 從根節點到第L層節點路徑長度是L-1

樹的路徑長度: 從根節點出發到每個節點的路徑長度之和

節點的權:如果給樹中每個節點賦予一個某種含義的數值,該數值稱為該節點的權值

節點的帶權路徑長度:從根節點到該節點的路徑長度與該節點的權值的乘積

樹的帶權路徑長度:所有葉子節點的帶權路徑長度之和 WPL

成績: <60		60~69    70~79		80~89     90~100
等級	  E       D			C		  B			A
比例   5%		  30%      40%        15%       10%     
    
 普通帶權二叉樹的WPL:
 	WPL=1*5+2*30+3*40+4*15+4*10 = 285
 哈夫曼樹的WPL:
 	WPL=40+2*30+3*15+4*5+4*10 = 205
    
 WPL是評價一棵帶權二叉樹優劣重要標準

哈夫曼樹:一定是一棵WPL最小的帶權二叉樹

構建哈夫曼樹:

1、把n個帶權節點先儲存一個集合F中,每個節點的左右子樹都為空

2、從F中選取根節點的權值最小的兩個節點作為左右子樹構成一棵新的二叉樹,左小右大,這顆二叉樹的根節點的權值等於兩個子樹權值之和

3、從F中刪除剛剛取出來的兩個節點,並把新形成的二叉樹根節點放入F中

4、重複步驟2、3,直到F中只剩下一棵樹,就是哈夫曼樹

哈弗曼編碼

目的:當年是為了解決遠距離通訊傳輸內容最優解問題

代傳送文字:ABBCD EEAFD

方法1:轉換成二進位制 001 總共要傳送30個二進位制數

方法2:

​ 1、根據字母出現頻率,構建哈夫曼樹

​ 假設:A 28 B 5 C 7 D 18 E 30 F 12、

​ 2、規定哈夫曼樹中左分支為0,右分支為1,從根節點出發到葉子節點經過的路徑分支組成的0和1的有序序列就是該葉子節點的哈弗曼編碼

​ A 10 B 0110 C 0111 D 00 E11 F010

​ ABBCD EEAFD哈夫曼編碼:100110011001110011111001000 總共27字元

​ 作用:資料壓縮、檔案壓縮也是一種解法

相關文章