c++堆

c++ reference: http://www.cplusplus.com/reference/algorithm/make_heap/

  heap并不屬于STL容器組件,它分為 max heap 和min heap,在缺省情況下,max-heap是優先隊列(priority queue)的底層實現機制。

而這個實現機制中的max-heap實際上是以一個vector表現的完全二叉樹(complete binary tree)。

  二叉堆(binary heap)就是i一種完全二叉樹。也即是。整棵二叉樹除了最底層的葉節點以外,都是填滿的,而最低層的葉子結點必須是從左到右不留空隙。

至于max-heap和min-heap,前者的任何一個父親結點都必須大于等于他的任意子結點,而后者相反。

?

下面我們利用數組來隱式表達這棵數:

  第0號元素保留,從arry[1]開始保存A,這時候我們可以輕易的看到:

  位于位置i的某個結點arry[i],他的左子結點必然在arry[2*i]中,右子結點必然位于arry[2*i+1],其父親結點必然位于arry[i/2]處。

  這種數組表達的方式我們 稱為 隱式表達。

  當然由于arry大小是靜態的,不能動態添加元素,我們可以使用vector來實現。

heap-算法:

1. push_heap(),新添加一個元素在末尾,然后重新調整堆序。也就是把元素添加在底層vector的end()處。

該算法必須是在一個已經滿足堆序的條件下,添加元素。該函數接受兩個隨機迭代器,分別表示first,end,區間范圍。

關鍵是我們執行一個siftup()函數,上溯函數來重新調整堆序。具體的函數機理很簡單,可以參考我的編程珠璣里面堆的實現的文章。

2. pop_heap(),這個算法跟push_heap類似,參數一樣。不同的是我們把堆頂元素取出來,放到了數組或者是vector的末尾,用原來末尾元素去替代,

然后end迭代器減1,執行siftdown()下溯函數來重新調整堆序。

注意算法執行完畢后,最大的元素并沒有被取走,而是放于底層容器的末尾。如果要取走,則可以使用底部容器(vector)提供的pop_back()函數。

3. sort_heap(),既然每次pop_heap可以獲得堆中最大的元素,那么我們持續對整個heap做pop_heap操作,每次將操作的范圍向前縮減一個元素。

當整個程序執行完畢后,我們得到一個非降的序列。

同理,sort_heap(RamdomAccessIteraor first,RamdomAccessIteraor end)接受兩個隨機迭代器作為參數。表示操作的范圍。

注意這個排序執行的前提是,在一個堆上執行。執行完之后序列也就失去了堆的性質。

#include<iostream> 
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<deque>
#include<map> 
#include<set>
#include <sstream>
using namespace std;void outHeap(vector<int> v){for(int i=0; i<v.size(); ++i)cout<<v[i]<<" ";cout<<endl;
}int main(){int myints[] = {10,20,30,5,15};vector<int> v(myints,myints+5);cout<<"建堆:"<<endl;make_heap(v.begin(), v.end());outHeap(v);cout<<endl;cout<<"往堆里插入一個元素:"<<endl;v.push_back(100);push_heap(v.begin(), v.end());outHeap(v);cout<<endl;cout<<"彈出堆頂元素,輸出下一個堆頂元素:" <<endl;cout<<"當前堆頂元素: "<<v.front()<<endl;pop_heap(v.begin(), v.end());v.pop_back();cout<<"下一個堆頂元素: "<<v.front()<<endl;cout<<endl;cout<<"排序堆:"<<endl;sort_heap(v.begin(), v.end());//默認從小到大 //sort_heap(v.begin(), v.end(), greater<int>());
    outHeap(v);//通過multiset實現最小堆 cout<<endl<<"通過multiset實現最小堆:"<<endl;multiset<int> mst(myints,myints+5);for(multiset<int>::iterator it = mst.begin(); it!=mst.end(); ++it) cout<<*it<<" ";cout<<endl;return 0;
} 

?4.一道很經典的題目就是在1億個數中找到最大的前100個數,這是一道堆應用題,找最大的前100個數,那么我們就創建一個大小為100的最小化堆,每來一個元素就與堆頂元素比較,因為堆頂元素是目前前100大數中的最小數,前來的元素如果比該元素大,那么就把原來的堆頂替換掉并重新調整堆。

5.例題:lintcode?滑動窗口的中位數 :?http://www.lintcode.com/zh-cn/problem/sliding-window-median/

?

//最無腦的解法....
class
Solution { public:/*** @param nums: A list of integers.* @return: The median of the element inside the window at each moving*/vector<int> medianSlidingWindow(vector<int> &nums, int k) {vector<int>v;vector<int> res;if (k > nums.size() || k == 0) return res;for(int i=0; i<k; ++i)v.push_back(nums[i]);sort(v.begin(), v.end());res.push_back(v[(k-1)/2]);for(int i=k; i<nums.size(); ++i){v.erase(lower_bound(v.begin(), v.end(), nums[i-k]));v.insert(lower_bound(v.begin(), v.end(), nums[i]), nums[i]);res.push_back(v[(k-1)/2]);}return res;} };
//使用multiset進行優化(內部以平衡二叉樹),感覺和上面的"最腦的解法差不多", 只不過是將一個有序的序列分成左右連個連續的序列,左邊序列的最后一個就是中位數
class
Solution { public:/*** @param nums: A list of integers.* @return: The median of the element inside the window at each moving*/vector<int> medianSlidingWindow(vector<int> &nums, int k) {// write your code herevector<int> res;if (k > nums.size() || k == 0) return res;multiset<int> left, right;//init heaps by first kth elements in numsfor (int i = 0; i < k; ++i) {left.insert(nums[i]);}while (left.size() > (k + 1) / 2) {right.insert(*left.rbegin());left.erase(left.find(*left.rbegin()));}res.push_back(*left.rbegin());//slide windowfor (int i = k; i < nums.size(); ++i) {//delete the leftmost element in window from heapsif (nums[i-k] > res.back()) right.erase(right.find(nums[i-k]));else left.erase(left.find(nums[i-k]));//insert new element into heapsif (!left.empty() && nums[i] <= *left.rbegin()) left.insert(nums[i]);else right.insert(nums[i]);//adjust heaps so that the left heap contains (k + 1) / 2 elementsif (left.size() < (k + 1) / 2) {left.insert(*right.begin());right.erase(right.begin());} else if (left.size() > (k + 1) / 2) {right.insert(*left.rbegin());left.erase(left.find(*left.rbegin()));}res.push_back(*left.rbegin());}return res;} };

?

轉載于:https://www.cnblogs.com/hujunzheng/p/5001898.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/531382.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/531382.shtml
英文地址,請注明出處:http://en.pswp.cn/news/531382.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于Ubuntu拒絕root用戶ssh遠程登錄

今天使用SecureCRT遠程登陸Ubuntu時一直提示密碼或用戶名錯誤&#xff0c;實際輸入是正確的&#xff0c;我按照網上教程改還是不行&#xff0c;后來才想起來我是root登錄的&#xff0c;Ubuntu默認的ssh遠程root登錄是關閉的&#xff0c;在這里記錄一下 1.編輯配置文件 #sudo v…

windows8建立局域網的方法

win8建立局域網的方法&#xff1a;1、首先筆記本有無線網卡且支持 虛擬WIFI ;2、按winX鍵&#xff0c;選擇"命令提示符(管理員)A"; 3、輸入"netsh wlan set hostednetwork modeallow ssid網絡名稱 key我的密碼" ; 4、接著輸入"netsh wlan start hoste…

內核移植出現:Kernel panic - not syncing: No init found.

今天在升級SDK的時候&#xff0c;升級到kernel時遇到如題所述的問題&#xff0c;花了天時間調通&#xff0c;在這里記錄一下。 報錯提示&#xff1a;(當時沒有記錄&#xff0c;錯誤的提示大概如下) Kernel panic - not syncing: No init found. Try passing init option to k…

lintcode Permutation Index

題目&#xff1a;http://www.lintcode.com/zh-cn/problem/permutation-index/ 排列序號 給出一個不含重復數字的排列&#xff0c;求這些數字的所有排列按字典序排序后該排列的編號。其中&#xff0c;編號從1開始。 樣例 例如&#xff0c;排列[1,2,4]是第1個排列。 思路&#xf…

32位和64位機器上C語言數據類型的大小

作為嵌入式開發的人員&#xff0c;是必須了解C語言在不同位數機器上占用的字節大小的&#xff0c;下面做下對比 不同位數平臺對比&#xff1a; \16位平臺32位平臺64位平臺char1個字節8位1個字節8位1個字節short2個字節16位2個字節16位2個字節int2個字節16位4個字節32位 4個字節…

lintcode循環數組之連續子數組求和

v 題目&#xff1a;連續子數組求和 II給定一個整數循環數組&#xff08;頭尾相接&#xff09;&#xff0c;請找出一個連續的子數組&#xff0c;使得該子數組的和最大。輸出答案時&#xff0c;請分別返回第一個數字和最后一個數字的值。如果多個答案&#xff0c;請返回其中任意一…

lintcode最長回文子串(Manacher算法)

題目來自lintcode, 鏈接&#xff1a;http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最長回文子串 給出一個字符串&#xff08;假設長度最長為1000&#xff09;&#xff0c;求出它的最長回文子串&#xff0c;你可以假定只有一個滿足條件的最長回文串。…

全排列總結

接觸全排列已經好長時間了&#xff0c;一直沒有抽空總結一下全排列的相關問題&#xff0c;下面來說一下&#xff01; 排列 一般地&#xff0c;從n個不同元素中取出m&#xff08;m≤n&#xff09;個元素&#xff0c;按照一定的順序排成一列&#xff0c;叫做從n個元素中取出m個元…

大小端問題傻傻分不清?

先來熟悉一下概念&#xff1a; 大端&#xff1a;數據的高位數據保存在低位地址&#xff0c;數據的低位數據保存在高地址 小端&#xff1a;數據的高位數據保存在高位地址&#xff0c;數據的低位數據保存在低地址為什么會存在大小端的問題&#xff1f; 這是因為在計算機系統中&a…

n個結點,不同形態的二叉樹(數目+生成)

題目鏈接&#xff1a; 不同的二叉查找樹&#xff1a;http://www.lintcode.com/zh-cn/problem/unique-binary-search-trees/ 不同的二叉查找樹 II&#xff1a;http://www.lintcode.com/zh-cn/problem/unique-binary-search-trees-ii/ 不同形態二叉樹的數目&#xff1a; 樣例 給出…

c++ stringstream(老好用了)

前言&#xff1a; 以前沒有接觸過stringstream這個類的時候&#xff0c;常用的字符串和數字轉換函數就是sscanf和sprintf函數。開始的時候就覺得這兩個函數應經很叼了&#xff0c;但是畢竟是屬于c的。c中引入了流的概念&#xff0c;通過流來實現字符串和數字的轉換方便多了。在…

mount --bind的用處

&#xff08;一&#xff09;mount --bind介紹 mount --bind的作用是將兩個目錄連接起來&#xff0c;例如&#xff1a;mount ---bind /dir1 /dir2 是將dir1目錄掛載到dir2目錄上&#xff0c;下面來實際演示一下&#xff1a; 上面的操作中首先創建了dir1 dir2兩個目錄&#xf…

gcc -strip編譯選項的作用

從字面上來看strip的意思是脫衣服、拆卸&#xff0c;那么gcc --strip的作用大概能猜錯來了。 沒錯就是有選擇地除去行號信息、重定位信息、調試段、typchk 段、注釋段、文件頭以及所有或部分符號表。 一旦使用該命令&#xff0c;則很難調試文件的符號&#xff0c;因此&#x…

lintcode 落單的數(位操作)

題目1 落單的數 給出2*n 1 個的數字&#xff0c;除其中一個數字之外其他每個數字均出現兩次&#xff0c;找到這個數字。 鏈接&#xff1a;http://www.lintcode.com/zh-cn/problem/single-number/ 樣例 給出 [1,2,2,1,3,4,3]&#xff0c;返回 4 挑戰 一次遍歷&#xff0c;常數級…

旋轉圖像

旋轉圖像 給定一個NN的二維矩陣表示圖像&#xff0c;90度順時針旋轉圖像。 看個例子 算法1&#xff1a; 如上圖所示&#xff0c;設一個N階二維矩陣&#xff0c;則將矩陣從外向里可以分成N/2個圈&#xff0c;例如&#xff08;1 2 3 4 8 12 16 15 14 13 9 5&#xff09;這是最外邊…

嵌入式開發板模擬器:QEMU

前兩天看微信公眾號時發現了一個嵌入式模擬器&#xff0c;感覺很不錯&#xff0c;自己動手安裝了一個&#xff0c;折騰了幾天&#xff0c;下載一直是個問題&#xff0c;特此記錄如下 模擬器大家應該都聽說過&#xff0c;有的小伙伴打游戲也會安裝模擬器&#xff0c;今天我們介紹…

gcc: weak_alias如何使用

本文主要說明weak和alias是什么和如何使用它 __attribute__是用來說明函數的屬性&#xff0c;weak和alias分別是兩個屬性。 &#xff08;一&#xff09;強符號和弱符號&#xff1a; 強符號&#xff1a;已經初始化的全局變量和未被weak修飾的函數弱符號&#xff1a;未初始化的全…

靜態Include和動態Include測試并總結

主要代碼 hjzgg.css .center-div{width:auto;margin-left: 40%;margin-right: 40%;display: block;position: absolute;top:0px;left:0px; }.text-div{margin-top: 80px; }.hjzgg-div{color:transparent;font-size:20px;font-weight: bold;letter-spacing:2px;-webkit-animatio…

linux終端常用快捷鍵

CTRLALTT 打開終端 CTRLD 關閉終端 CTRL SHIFT "" 放大終端字體 CTRL “-” 縮小終端字體 CTRL r 查找歷史命令 CTRLu 刪除光標前面所有內容 CTRLw 刪除光標左邊的單詞 CTRL k 刪除光標后面的所有內容 CTRLL 清除當前屏幕內容 CTRLa 光標移到開始位置 CTRLe 光標移到…

ueditor的配置和使用

ueditor下載好之后直接復制到項目的WebContent目錄下&#xff0c;并將ueditor\jsp\lib下的jar包復制或者剪切到項目的lib目錄下。先看一下效果&#xff0c;如下&#xff1a; 1.文件的上傳 首先在ueditor/jsp目錄下找到config.json文件&#xff0c;就拿Image上傳來說吧。 "…