左倾堆
???左傾堆(或左偏樹)和之前記錄過的二叉堆一樣,是堆的一種;和普通的二叉堆不同,它是一種可合并堆。可合并堆相比于普通的二叉堆在對兩個堆進行合并的操作上具有很大的優勢:對于基本的二叉堆合并,時間復雜度為O(n), 而對于可合并堆,其時間復雜度為O(log2n).
左傾堆性質
????左傾堆(也叫左偏樹),是一種可合并堆.它有以下性質:
左傾堆合并
????可合并堆相比普通二叉堆在進行堆的合并上具有很大優勢,對于左傾堆而言,合并操作為核心操作,像插入、刪除操作等都可以在合并操作的基礎上完成:插入操作可以將新插入的元素視為一個堆,然后進行兩個左傾堆的合并;刪除操作(堆的刪除總是從堆頂位置取出元素)去除堆頂元素之后,將堆頂元素的左子堆和右子堆進行合并。?
????左傾堆的合并過程為:
關于堆合并的具體過程,可以參考?左傾堆-圖文解析
實現(c++)
????二叉堆和可合并堆經常用在優先隊列(priority queue)中,下面的代碼就進行了堆的合并、元素的入隊和出隊
#include<iostream> using namespace std;struct TreeNode{int key;int npl;TreeNode* left;TreeNode* right;TreeNode(int k){key = k;npl = 0;left = right = NULL;} }; void Swap(TreeNode* node1, TreeNode* node2){TreeNode* tmp = node1;node1 = node2;node2 = tmp; }//左傾堆的合并操作 TreeNode* Merge(TreeNode* heap1, TreeNode* heap2){//如果其中一個為空堆,則直接返回另外一個if (!heap1)return heap2;if (!heap2)return heap1;//選擇“較小堆”,將其根節點作為新堆的根節點if (heap1->key > heap2->key){Swap(heap1, heap2);}//將較小堆的右子堆和較大堆進行合并,并置為較小堆的右子堆heap1->right = Merge(heap1->right, heap2);if (heap1->left == NULL || (heap1->left && heap1->right && heap1->left->npl < heap1->right->npl)){ //如果堆的根節點的左子結點的npl小于右子節點的npl,則交換左右子節點Swap(heap1->left, heap1->right);}if (heap1->right == NULL)heap1->npl = 1;elseheap1->npl = heap1->right->npl + 1; //新堆的npl設為右子節點的npl +1return heap1; }//將元素k插入堆 heap中,即元素入隊。 注意這里使用指針的引用 void Enqueue(TreeNode*& heap, int k){if (!heap){heap = new TreeNode(k);return;}TreeNode* new_heap = new TreeNode(k);heap = Merge(heap, new_heap); }//元素出隊,注意這里使用指針的引用 int Dequeue(TreeNode*& heap){int result = heap->key;heap = Merge(heap->left, heap->right);return result; }?
總結
- 上一篇: CSS3盒子阴影box-shadow
- 下一篇: 使用 COM 风格的编程接口