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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++实现最大堆最小堆

發布時間:2025/3/15 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++实现最大堆最小堆 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

堆和棧的區別

最大堆與最小堆

最大堆的操作

最大堆的插入操作

最大堆的彈出操作

最大堆的C++代碼實現

最小堆概念

最小堆的插入操作

最小堆的彈出操作

最小堆的C++代碼實現

最大堆最小堆的應用

1.priority_queue

2. STL 堆操作


堆和棧的區別

  一、堆棧空間分配區別:
  1、棧(操作系統):由操作系統自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧;
  2、堆(操作系統): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似于鏈表。
  二、堆棧緩存方式區別:
  1、棧使用的是一級緩存, 他們通常都是被調用時處于存儲空間中,調用完畢立即釋放;
  2、堆是存放在二級緩存中,生命周期由虛擬機的垃圾回收算法來決定(并不是一旦成為孤兒對象就能被回收)。所以調用這些對象的速度要相對來得低一些。
  三、堆棧數據結構區別:
  堆(數據結構):堆可以被看成是一棵樹,如:堆排序;

  棧(數據結構):一種先進后出的數據結構。

最大堆與最小堆

最大堆:根結點的鍵值是所有堆結點鍵值中最大者,且每個結點的值都比其孩子的值大。

最小堆:根結點的鍵值是所有堆結點鍵值中最小者,且每個結點的值都比其孩子的值小。

最小堆和最大堆的增刪改相似,其實就是把算法中的大于改為小于,把小于改為大于。

最大堆的操作

在生成最大堆時,我們可以采取一次次遍歷整棵樹找到最大的結點放到相應的位置中。但是這種方法有個不好的地方,就是每個結點都要重復比較多次。

所以我們可以換一種思考的順序,從下往上進行比較。先找到最后一個有子結點的結點,先讓他的兩個子結點進行比較,找到大的值再和父結點的值進行比較。如果父結點的值小,則子結點和父結點進行交換,交換之后再往下比較。然后一步步遞歸上去,知道所在結點的位置是0號位置跳出。這樣就可以有效地減少比較所用到的時間。

但是每一次交換都要重復三步:temp = heap[i]; heap[i] = heap[j]; heap[j] = temp;

當樹的結構比較大的時候,就會浪費很多時間。所以我們可以先把父結點的值存到temp中跟子結點比較,如果子結點大的話就把子結點的值賦值給父結點,再往下比較,最后才把temp的值存到相應的位置。

最大堆的插入操作

每當插入一個元素,將元素插入到容器(數組)尾部,然后執行迭代的上升操作,將插入的元素與其父節點比較,若比父節點大則交換,然后再與交換后節點的父節點相互比較交換,直到放置到合適位置。(最壞遞歸到根節點終止迭代)

最大堆的彈出操作

彈出最大值(即數組首地址元素 a[0])。先交換交換堆頂與堆末,再彈出堆末(最大值),然后再將現堆頂元素執行迭代的下降操作,若其子節點存在與其子節點比較,若比子節點小則交換,然后再與交換后的子節點相互比較交換,直到放置在合適位置。(最壞遞歸到葉子節點)

最大堆的C++代碼實現

#include <iostream> #include<vector> using namespace std;#define ElementType int//構造大頂堆類 class MaxHeap { private:vector<ElementType> a; public://構造大頂堆MaxHeap(ElementType elements[], int number){for (int i = 0; i < number; i++){a.push_back(elements[i]);}for (int i = a.size() / 2 - 1; i >= 0; i--){down(i);}}//交換i,j下標對應元素void swap(int i, int j){ElementType temp = a[i];a[i] = a[j];a[j] = temp;}//上升操作void up(int i){int fa = (i - 1) / 2;//f表示父節點下標if (i > 0 && a[i] > a[fa]){swap(i, fa);up(fa);//如果一直比父節點大,遞歸到根節點(下標0)}}//插入點void push(ElementType p){a.push_back(p);up(a.size() - 1);//上升操作 直到合適位置}//下降操作void down(int i){int son = 2 * i + 1;//son表示子節點下標if (son < a.size()){if (son + 1 < a.size() && a[son] < a[son + 1]){son++; //取值兩個子節點 值更大的節點下標}//若子節點大,交換if (a[i] < a[son]){swap(i, son);}down(son);//遞歸調用,直到葉子節點}}//彈出堆頂節點(最大)ElementType pop(){ElementType result = a[0];swap(0, a.size() - 1);//交換堆頂與堆末a.pop_back();//彈出down(0);//再將原來的最末元素(現在的堆頂元素)下降操作,使之到合適位置return result;}//輸出堆(順序輸出)void show(){for (int i = 0; i < a.size(); i++) {cout << " " << a[i];}cout << endl;} }; int main(void) {int a[] = { 13,43,84,96,22,65,70,47 };MaxHeap* m = new MaxHeap(a, 8);//測試cout << "顯示當前最大堆:" << endl;m->show();cout << "彈出最大堆頂的元素:" << m->pop() << endl;cout << "顯示當前最大堆:" << endl;m->show();cout << "插入一個節點90:" << endl;m->push(90);cout << "顯示當前最大堆:" << endl;m->show();return 0; }

最小堆概念

最小堆,是一種經過排序的完全二叉樹,其中任一非終端節點的數據值均不大于其左子節點和右子節點的值。堆內的所有數據中最小的元素始終在堆頂,而增刪一個元素而動態維護最小堆性質的時間復雜度僅為 O(logN)

最小堆的插入操作

每當插入一個元素,將元素插入到容器(數組)尾部,然后執行迭代的上升操作,將插入的元素與其父節點比較,若比父節點小則交換,然后再與交換后節點的父節點相互比較交換,直到放置到合適位置。(最壞遞歸到根節點終止迭代)

最小堆的彈出操作

彈出最小值(即數組首地址元素 a[0])。先交換交換堆頂與堆末,再彈出堆末(最小值),然后再將現堆頂元素執行迭代的下降操作,若其子節點存在與其子節點比較,若比子節點小則交換,然后再與交換后的子節點相互比較交換,直到放置在合適位置。(最壞遞歸到葉子節點)

最小堆的C++代碼實現

#include <iostream> #include<vector> using namespace std;#define ElementType intclass MinHeap { private:vector<ElementType> a; public://構造小頂堆MinHeap(ElementType elements[], int number){for (int i = 0; i < number; i++){a.push_back(elements[i]);}for (int i = a.size() / 2 - 1; i >= 0; i--){down(i);}}//交換i,j下標對應元素void swap(int i, int j){ElementType temp = a[i];a[i] = a[j];a[j] = temp;}//上升操作void up(int i){int fa = (i - 1) / 2;//f表示父節點下標if (i > 0 && a[i] < a[fa]){swap(i, fa);up(fa);//如果一直比父節點小,遞歸到根節點(下標0)}}//插入點void push(ElementType p){a.push_back(p);up(a.size() - 1);//上升操作 直到合適位置}//下降操作void down(int i){int son = 2*i + 1;//son表示子節點下標if (son < a.size()){if (son + 1 < a.size() && a[son] > a[son + 1]){son++; //取值兩個子節點 值更小的節點下標}//若子節點小,交換if (a[i] > a[son]){swap(i, son);}down(son);//遞歸調用,直到葉子節點}}//彈出堆頂節點(最小)ElementType pop(){ElementType result = a[0];swap(0, a.size() - 1);//交換堆頂與堆末a.pop_back();//彈出down(0);//再將原來的最末元素(現在的堆頂元素)下降操作,使之到合適位置return result;}//輸出堆(順序輸出)void show(){for (int i = 0; i < a.size(); i++){cout << " " << a[i];}cout << endl;} };int main(void) {int a[] = { 13, 43, 84, 96, 22, 65, 70, 47 };MinHeap* m = new MinHeap(a, 8);//測試cout << "顯示當前最小堆:" << endl;m->show();cout << "彈出最小堆頂的元素:" << m->pop() << endl;cout << "顯示當前最小堆:" << endl;m->show();cout << "插入一個節點30:" << endl;m->push(30);cout << "顯示當前最小堆:" << endl;m->show();return 0; }

最大堆最小堆的應用

1.priority_queue

2. STL 堆操作

頭文件是#include <algorithm>
一般用到這四個:make_heap()、pop_heap()、push_heap()、sort_heap();

總結

以上是生活随笔為你收集整理的C++实现最大堆最小堆的全部內容,希望文章能夠幫你解決所遇到的問題。

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