日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

左倾堆

發布時間:2025/5/22 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 左倾堆 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

???左傾堆(或左偏樹)和之前記錄過的二叉堆一樣,是堆的一種;和普通的二叉堆不同,它是一種可合并堆。可合并堆相比于普通的二叉堆在對兩個堆進行合并的操作上具有很大的優勢:對于基本的二叉堆合并,時間復雜度為O(n), 而對于可合并堆,其時間復雜度為O(log2n).

左傾堆性質

????左傾堆(也叫左偏樹),是一種可合并堆.它有以下性質:

  • 每個節點含有左子結點指針、右子節點指針、鍵值key、NPL(Null Path Length,表示當前節點到最近的一個不滿子節點的長度,不滿節點指的是節點含有少于兩個子節點)
  • 每個節點的鍵值都小于其左右子節點的鍵值(最小堆的性質)
  • 每個節點的左子節點的NPL 大于等于 右子節點的NPL
  • 節點的NPL值等于其右子節點的NPL值 + 1
  • 左傾堆的左右子節點及其下方節點構成的堆也分別都是左傾堆
  • 葉子節點的NPL值等于0,空節點的NPL值等于 -1
  • 左傾堆合并

    ????可合并堆相比普通二叉堆在進行堆的合并上具有很大優勢,對于左傾堆而言,合并操作為核心操作,像插入、刪除操作等都可以在合并操作的基礎上完成:插入操作可以將新插入的元素視為一個堆,然后進行兩個左傾堆的合并;刪除操作(堆的刪除總是從堆頂位置取出元素)去除堆頂元素之后,將堆頂元素的左子堆和右子堆進行合并。?
    ????左傾堆的合并過程為:

  • 如果一個空左傾堆和一個非空左傾堆進行合并,直接返回非空左傾堆
  • 如果兩個左傾堆都非空,比較兩個堆的根節點,去除較小的堆的根節點作為新的根節點。然后將“較小堆”的根節點的右子節點(和它下方的堆)和“較大堆”進行合并(遞歸)
  • 如果新堆的右子節點的NPL大于左子結點的NPL,則交換左右子節點
  • 設置新堆的根節點的NPL = 右子節點的NPL + 1
  • 關于堆合并的具體過程,可以參考?左傾堆-圖文解析

    實現(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; }

    ?

    總結

    以上是生活随笔為你收集整理的左倾堆的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。