【数据结构】用模版实现大小堆、实现优先级队列,以及堆排序

原创 2016年05月30日 15:04:33

    一、用模版实现大小堆


    如果不用模版的话,写大小堆,就需要分别实现两次,但是应用模版的话问题就简单多了,我们只需要实现两个仿函数,Greater和Less就行了,仿函数就是用类实现一个()的重载就实现了仿函数。这个看下代码就能理解了。再设计参数的时候,需要把模版设计成模版的模版参数,因为要实现大小堆嘛!当我们实现好一个大堆或者小队的逻辑后只需要用模版接收的Greater或Less类定义一个变量,就能实现通用功能了。


template<typename T>
struct Less
{
    bool operator()(const T& l, const T& r)
    {
        return l < r;
    }
};

template<class T>
struct Greater
{
    bool operator()(const T& l, const T& r)
    {
        return l>r;
    }
};

template <class T,template<class> class compare = less>
class Heap
{
public:
    Heap()
    {}

    Heap(T* a,size_t size)
    {
        size_t index = 0;
        while (index < size)
        {
            _a.push_back(a[index]);
            index++;
        }

        for (int i = (_a.size() - 2) / 2; i >= 0; i--)
            _AdjustDown(i);
    }

    void push(const T& x)
    {
        _a.push_back(x);
        _AdjustUp(_a.size() -1);
    }

    void pop()
    {
        size_t size = _a.size();
        assert(size > 0);
        swap(_a[0], _a[size - 1]);
        _a.pop_back();
        size = _a.size();
        _AdjustDown(0);
    }

    size_t top()
    {
        assert(!_a.empty());

        return _a[0];
    }

    bool empty()
    {
        return _a.size() == 0;
    }

    size_t Size()
    {
        return _a.size();
    }

    void Print()
    {
        for (int i = 0; i < _a.size(); i++)
        {
            cout << _a[i] << " ";
        }
        cout << endl;
    }

protected:
    void _AdjustUp(int child)
    {
        int parent = (child - 1) / 2;
        compare<T> com;  //如果是大堆传过来就是用大堆的逻辑,小堆就实现小堆的逻辑
        while (child > 0)
        {
            //找出孩子中的最大孩子
            if (com(_a[child] , _a[parent]))
            {
                swap(_a[child], _a[parent]);
                child = parent;
                parent = (child - 1) / 2;
            }
            else
            {
                break;
            }
        }

    }

    void _AdjustDown(size_t parent)
    {
        size_t child = 2 * parent + 1;
        compare<T> com; //如果是大堆传过来就是用大堆的逻辑,小堆就实现小堆的逻辑
        while (child < _a.size())
        {
            //找出孩子中的最大孩子
            if (child + 1 < _a.size() && com(_a[child+1] ,_a[child]))
            {
                ++child;
            }
            //把
            if (com(_a[child] , _a[parent]))
            {
                swap(_a[parent], _a[child]);
                parent = child;
                child = child * 2 + 1;
            }
            else
            {
                break;
            }
        }

    }
protected:
    vector<T> _a;
};


   二、用模版实现优先级队列


前面实现了大小堆,这里我们可以使用适配器,直接调用大小堆,来实现优先级队列。


template<class T, template<class> class compare = Less>
class priorityQueue
{
private:
    Heap<T, compare> _hp; 
public:
    void push(const T& x)
    {
        _hp.push(x);
    }

    void pop()
    {
        _hp.pop();
    }

    T& Top()
    {
        return _hp.top();
    }

    void Print()
    {
        _hp.Print();
    }

};


    三、堆排序的实现


    堆排序的实现简单思路,(升序)先构造出来一个大堆,调整堆后,将堆头和最后一个数据交换,最大值就换到了数组的最后,然后在调整堆,但是size需要减少1,因为最大的已经调整到最后,如果再加上它调整又会回到堆头。

int*& HeapSort(int* a, size_t size)
{
    for (int i = (size - 2) / 2; i >= 0; i--)
    {
        _AdjustDown(a, size, i);
    }

    for (int i = 0; i < size; i++)
    {
        swap(a[0], a[size - i - 1]);
        _AdjustDown(a, size - i - 1, 0);
    }

    return a;
}


本文出自 “滴水” 博客,请务必保留此出处http://10740329.blog.51cto.com/10730329/1768172

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zangyuanan320/article/details/51538141

堆的实现(大小堆及 优先队列)

一、堆的概念    堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。  堆结构的二叉树存储是:  最大堆:每个父节点的都大于孩子节点。  最小堆:每个父节点的都小于孩子节点。     堆栈中...
  • l_tudou
  • l_tudou
  • 2016-05-26 09:38:15
  • 1349

数据结构之大小堆&&优先级队列

大小堆> 一.什仫是堆?     堆这种数据结构说白了就是一颗完全二叉树,堆的含义说明这颗完全二叉树中的所有非终端结点的值均不大于(或不小于)其左,右孩子结点的值.若一维数组{k1,k2,k3,k4....
  • qq_34328833
  • qq_34328833
  • 2016-10-11 19:34:10
  • 844

scala数据结构和算法-08-堆排序

二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。 当父结点的键值总是大于或...
  • hxpjava1
  • hxpjava1
  • 2017-01-03 16:45:07
  • 617

数据结构基础加强之最小堆的实现与堆排序

最小堆的实现及堆排序
  • a815060271
  • a815060271
  • 2017-05-16 19:15:11
  • 136

[数据结构]最小堆的类模板实现

堆数据结构是一种数组对象,它可以被视为一科完全二叉树结构。它的特点是父节点的值大于(小于)两个子节点的值(分别称为最大堆和最小堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。1...
  • u013467442
  • u013467442
  • 2015-07-30 18:06:26
  • 1681

堆与堆排序与topK问题

堆与堆排序与topK问题
  • xmkid
  • xmkid
  • 2016-04-11 20:26:06
  • 1292

JavaScript数据结构之 堆排序

以前没学过这种排序,今天看了一下,最好、最坏时间复杂度都是nlog2n。 原理可以参考这篇博客,里面的图不错 http://blog.csdn.net/xiaoxiaoxuewen/article/...
  • liuyaqi1993
  • liuyaqi1993
  • 2017-04-07 16:45:40
  • 571

拓扑排序--九度.1449.[优先级队列实现小顶堆]

题目:http://ac.jobdu.com/problem.php?pid=1449思路: 题目要求输出排名实际就是输出拓扑序列,使用vector和queue并不难实现; 主要是其要求在有多个序列...
  • qq_26398495
  • qq_26398495
  • 2017-02-28 20:47:41
  • 162

[数据结构]堆排序的C语言简单实现

堆排序的C语言简单实现
  • tudaodiaozhale
  • tudaodiaozhale
  • 2017-12-10 14:22:31
  • 141

了解堆排序并用js实现

根据《算法导论》梳理了堆排序的流程并根据流程用js进行了实现
  • longpersevere
  • longpersevere
  • 2017-10-31 10:49:25
  • 105
收藏助手
不良信息举报
您举报文章:【数据结构】用模版实现大小堆、实现优先级队列,以及堆排序
举报原因:
原因补充:

(最多只允许输入30个字)