數據結構--左式堆的思想和代碼
阿新 • • 發佈:2017-05-09
child 靈魂 init esp 每一個 all 短路徑 out single
左式堆也是實現優先列隊的一種數據結構,和二叉堆一樣,左式堆也具有堆序性和結構性。
堆序性: 一個節點的後裔都大於等於這個節點。
結構性:左式堆也是二叉樹,和二叉堆的唯一區別在於左式堆不是理想平衡的,實際上是趨於非常不平衡,對於堆中每一個節點X,左兒子的零路徑長至少與右兒子的零路徑長一樣大,零路徑長Npl的定義為:節點到一個沒有兩個兒子的節點的最短路徑長,因此具有0個或者1個兒子節點的Npl為0,Npl(NULL) = -1。
左式堆可以高效的支持合並操作,而插入和刪除操作都可以通過合並操作來實現,相關的代碼如下:
#include<iostream> using namespace std; struct TreeNode; typedef struct TreeNode *PriorityQueue; PriorityQueue Init(void); int FindMin(PriorityQueue H); bool IsEmpty (PriorityQueue H); PriorityQueue Merge(PriorityQueue H1,PriorityQueue H2); //合並操作 #define Insert(x,H) (H = Insert1(x,H)) PriorityQueue Insert1 (int x,PriorityQueue H); PriorityQueue DeleteMin1(PriorityQueue H); struct TreeNode { int Element; PriorityQueue Left; PriorityQueue Right; int Npl; //零路徑長,節點X到一個沒有兩個兒子的節點的最短路徑的長 }; static void SwapChildren (PriorityQueue H) //交換根節點的左右子樹 { PriorityQueue temp; temp = H->Right; H->Right = H->Left; H->Left = temp; } static PriorityQueue Merge1(PriorityQueue H1,PriorityQueue H2) { if(H1->Left == NULL) //H1為單點,就一個元素 H1->Left = H2; else { H1->Right = Merge(H1->Right,H2); if(H1->Left->Npl < H1->Right->Npl) SwapChildren(H1); H1->Npl = H1->Right->Npl + 1; } return H1; } PriorityQueue Merge(PriorityQueue H1,PriorityQueue H2) //處理特殊情況 { if(H1 == NULL) return H2; if(H2 == NULL) return H1; if(H1->Element < H2->Element ) return Merge1(H1,H2); else return Merge1(H2,H1); } PriorityQueue Insert1(int x,PriorityQueue H) //把x看成但節點,執行合並操作,思想很巧妙 { PriorityQueue SingleNode; SingleNode = (PriorityQueue)malloc(sizeof(struct TreeNode)); if(SingleNode == NULL) cout << "out of space" << endl; else { SingleNode->Element = x; SingleNode->Left = NULL; SingleNode->Npl = 0; SingleNode->Right = NULL; H = Merge(SingleNode, H); } return H; } bool IsEmpty(PriorityQueue H) { if(H == NULL) return true; else return false; } PriorityQueue DeleteMin(PriorityQueue H) //刪除操作,因為左式堆的堆序性,最小值就在根處,因此刪除操作直接就是把根的左子樹和右子樹合並即可 { PriorityQueue LeftHeap,RightHeap; if(IsEmpty(H)) { cout << "Priority queue is Empty" << endl; return H; } LeftHeap = H->Left; RightHeap = H->Right; free(H); return Merge(LeftHeap,RightHeap); } int main () { return 0; }
插入和刪除操作都可以通過合並操作來實現,這種思想很巧妙,值得我們學習。
夜深了,,,
網易雲的歌單循環到了《願得一人心》這首鋼琴曲,音樂都是有靈魂的,只願得一人心,白首不分離。
數據結構--左式堆的思想和代碼