堆排序重要算法:向上向下调整算法

来源:互联网 发布:2万工资的java程序员 编辑:程序博客网 时间:2024/06/03 22:01

        stl中并没有堆这样一个类,只是存放了堆的种种算法,但是在学习中我们可以模拟实现堆,把它封装为一个类,然后在运用当中调用它的各种接口,实现一次可以深入理解堆排序的原理和优势,使我们在面对各种问题的时候可以借助这个算法实现更好的优化。

        接下来就让我们看一下具体的实现过程:

       这里是头文件和命名空间的包函

#pragma once#include <iostream>#include <vector>#include <assert.h>using namespace std;


这里是模拟实现的堆数据结构        

template<class T, class Compare>class Heap{public:Heap() //无参构造函数{}Heap(const T* a, size_t n)  //使用数组初始化堆{size_t i = 0;_a.reserve(n);for (i = 0; i < n; i++){_a.push_back(a[i]);}int parent = (n - 1) / 2;for (parent; parent >= 0; parent--){adjustdown(parent); //建堆需要实现的向下调整算法;}}void Push(const T& x){_a.push_back(x);adjustup(_a.size()-1);    //这是向上调整算法}void Pop(){assert(_a.size());swap(_a[0],_a[_a.size()-1]);_a.pop_back();adjustdown(0);}protected:void adjustup(int child){assert(child < _a.size()&& child >0);Compare cmp;  //这里的cmp和下面向下调整算法得cmp都是一个仿函数类,用仿函数主要是为了实现代码的复用.int parent = (child - 1) / 2;while (child > 0){if (cmp(_a[child] , _a[parent])){swap(_a[child], _a[parent]);child = parent;parent = (parent - 1) / 2;}else{break;}}}void adjustdown(int parent){Compare cmp;size_t child = parent * 2 + 1;while (child<_a.size()){if (child + 1 < _a.size() && cmp(_a[child + 1] , _a[child]))child++;if (cmp(_a[child],_a[parent])){swap(_a[child], _a[parent]);parent = child;child = child * 2 + 1;}else{break;}}}protected:vector<T> _a;};
             代码中蕴含了很多算法,但是只有代码晦涩难懂。所以绘制了几幅图便于理解。


下面我们主要看一下adjustdown 和dijustup这两个函数的算法



              这里我们就将堆中的基本算法实现了。有了这个算法思路或者实例化后的结构我们就可以实现排序、topk问题等利用别的算法实现起来很麻烦的问题。


原创粉丝点击