zoukankan      html  css  js  c++  java
  • 算法导论第三版--堆的生成,排序,插入

    这两年一直埋首在C相关的代码中,都快忘记自己曾经热爱并赖以南征北战过的C++了,而且C++11出来那么久了,瞄了几眼,没练过都不敢说自己会C++了,

    正好很多基础算法没正经的学习过,打算逐个(算法导论里的)用C++完成一遍好好练练手。(其实没那么多时间,能写几个就写几个啦,加之水平有限)

    结果呢,一动起手来,还是觉得实现算法呢,还是C看起来舒服,C++反而不直观了,咋的整呢,管不了那么多了,写几行看看吧。

    嗯,工欲善其事必先利其器,这里推荐编辑器code::blocks+mingw,清新好用,(当然vs更好用,不过你懂的啦),博主最后还是回到了eclipse的怀抱,refactor,debug功能比code::blocks好一点

    堆有2种,最大堆和最小堆,其实就是一个比较因子的不同,算法描述是一样的。

    heapify函数用来保持堆的特性,比如:

    1、父节点总是大于子节点这是最大堆,反之,父节点总是小于子节点是最小堆

    2、使用数组或者vector来实现堆比较方便,索引为i的元素,父节点就是i/2,左子节点是2*i,右子节点是2*i+1,i>=1。

    3、插入一个新元素,在尾部插入最快,但是可能会破坏堆的特性,因此要注意重新保持堆的特性

    另外,采用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 }

    参考: 算法导论

  • 相关阅读:
    BZOJ3295:[CQOI2011]动态逆序对——题解
    BZOJ1176:[Balkan2007]Mokia——题解
    测试用例设计白皮书--等价类划分方法
    测试用例设计白皮书--等价类划分方法
    软件测试价值观-SMBT新理念
    软件测试价值观-SMBT新理念
    Web自动化测试平台设计与落地-概览
    Web自动化测试平台设计与落地-概览
    Web自动化测试平台设计与落地-概览
    自动化测试平台设计与落地-概览
  • 原文地址:https://www.cnblogs.com/danxi/p/6438931.html
Copyright © 2011-2022 走看看