算法導論第三版--堆的生成,排序,插入

這兩年一直埋首在C相關的代碼中,都快忘記本身曾經熱愛並賴以南征北戰過的C++了,並且C++11出來那麼久了,瞄了幾眼,沒練過都不敢說本身會C++了,ios

正好不少基礎算法沒正經的學習過,打算逐個(算法導論裏的)用C++完成一遍好好練練手。(其實沒那麼多時間,能寫幾個就寫幾個啦,加之水平有限)算法

結果呢,一動起手來,仍是以爲實現算法呢,仍是C看起來舒服,C++反而不直觀了,咋的整呢,管不了那麼多了,寫幾行看看吧。api

嗯,工欲善其事必先利其器,這裏推薦編輯器code::blocks+mingw,清新好用,(固然vs更好用,不過你懂的啦),博主最後仍是回到了eclipse的懷抱,refactor,debug功能比code::blocks好一點數組

 

堆有2種,最大堆和最小堆,其實就是一個比較因子的不一樣,算法描述是同樣的。數據結構

heapify函數用來保持堆的特性,好比:less

一、父節點老是大於子節點這是最大堆,反之,父節點老是小於子節點是最小堆eclipse

二、使用數組或者vector來實現堆比較方便,索引爲i的元素,父節點就是i/2,左子節點是2*i,右子節點是2*i+1,i>=1。編輯器

三、插入一個新元素,在尾部插入最快,可是可能會破壞堆的特性,所以要注意從新保持堆的特性函數

 

另外,採用C++也有不少方便之處,好比有現成的functor可使用。這只是個例子,請在實際工做中謹慎選擇合適的數據結構或者容器。學習

 1 #include <iostream>
 2 #include <vector>
 3 #include <cmath>
 4 #include <cassert>
 5 #include <functional>
 6 
 7 using std::floor;
 8 using std::swap;
 9 using std::vector;
10 using std::greater;
11 using std::less;
12 
13 template<typename _InIt, typename _Func>
14 void heapify(_InIt first, _InIt last, _InIt ite, _Func& Func) {
15     int i = ite - first;
16     _InIt it = ite;
17 
18     if ((last-ite)>i && Func(*(ite+i), *(it))) {
19         it = ite + i;
20     }
21 
22     if ((last-ite)>(i+1) && Func(*(ite+i+1), *(it))) {
23         it = ite + i + 1;
24     }
25 
26     if (*it != *ite) {
27         swap(*ite, *it);
28         heapify(first, last, it, Func);
29     }
30 }
31 
32 template<typename _InIt, typename _Func>
33 void build_heap(_InIt first, _InIt last, _Func &Func) {
34     int i = (int)floor((float)(last - first)/2);
35     for (; i>0; i--) {
36         heapify(first, last, first+i, Func);
37     }
38 }
39 
40 template<typename _InIt, typename _Func>
41 void heap_sort(_InIt first, _InIt last, _Func &Func) {
42     for (_InIt it=(last-1); it != (first+1); --it) {
43         swap(*(first+1), *it);
44         heapify(first, it, first+1, Func);
45     }
46 }
47 
48 template<typename T, typename _Func>
49 T heap_extract(vector<T> &v, _Func &Func) {
50     assert(v.size() >= 2);  /* 由於多了一個填充元素 */   
51 
52     typename vector<T>::iterator it = v.begin() + 1;  /* 沒有加typename gcc會報錯 */
53     T target = *(it);
54 
55     v.erase(it);
56     heapify(v.begin(), v.end(), v.begin()+1, Func);
57     return target;
58 }
59 
60 template<typename T, typename _Func>
61 void heap_increase_key(vector<T>& v, _Func &Func, int i, T key) {
62     v[i] = key;
63     while(i>1 && !Func(v[i/2], v[i])) {
64         swap(v[i], v[i/2]);
65         i >>= 1;
66     }
67 }
68 
69 template<typename T, typename _Func>
70 void heap_insert(vector<T> &v, T key, _Func &Func) {
71     v.push_back(key);
72     heap_increase_key(v, Func, v.size()-1, key);
73 }
74 
75 int main(int argc,  char* argv[]) {
76     /* 堆的索引是1開始,因此第一個元素0是用來佔位的 */
77     int lst[] = {0,3,7,8,14,2,1,9,4,10,16};   
78     vector<int> v(lst, lst+11);
79 
80     less<int> c;
81     build_heap(v.begin(), v.end(), c);
82 
83     std::cout << heap_extract(v, c) << std::endl;
84     heap_sort (v.begin(), v.end(), c);
85 
86     for (vector<int>::iterator it=v.begin(); it!=v.end(); ++it) {
87         std::cout << *it << " ";
88     }
89     std::cout << std::endl;
90 
91     return 0;
92 }

 

參考: 算法導論

相關文章
相關標籤/搜索