• 优先队列的应用 C++实现


    优先队列的应用 C++实现

    优先队列可以用堆来实现, 堆底层可以用数组表示,
    通过索引关系,可以表示成一颗二叉完全树

    C++的STL提供了相应的容器适配器
    包含在queue头文件中

    下面通过一道题来看如何使用它

    给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

    string frequencySort(string s) {
    }
    

    首先,统计字符出现的频率,通过map容器可以很简单的统计出来

    map<char, int> mp;
    
    for (auto e : s)
    {
        ++mp[e];
    }
    

    然后我们需要构建一个优先队列,而且要指定优先队列的排序方式
    因此我们定义了一个自己的结构体, 并定义了<操作符(降序定义小于号,升序大于号),

    struct Node
    {
        Node(const pair<char, int> &val) : p(val) {}
        pair<char, int> p;
    };
    
    bool operator<(const Node &a, const Node &b)
    {
        return a.p.second < b.p.second;
    }
    

    然后把键值对放入优先队列中

    priority_queue<Node, vector<Node>, less<Node>> pq;
    for (auto e : mp)
    {
        pq.push(make_pair(e.first, e.second));
    }
    

    要用的时候,依次取出来就是了,每次取出的都是里面最大(或最小)的

    string res;
    while (!pq.empty())
    {
        for (int i = 0; i < pq.top().p.second; ++i)
            res.push_back(pq.top().p.first);
        pq.pop();
    }
    

    还有好几个类似的题,都可以用这种方式解决

    比如 :

    下面是堆的实现, 还是建议掌握的

    #include <vector>
    using namespace std;
    
    template <class T>
    class Heap
    {
      public:
        Heap(size_t maxElems)
        {
            h = new HeapStruct;
            h->Elems = new T[maxElems + 1];
            h->Capacity = maxElems;
            h->size = 0;
        }
        ~Heap()
        {
            destroy();
        }
        void insert(T x)
        {
            size_t i;
            if (isFull())
            {
                return;
            }
            for (i = ++h->size; i / 2 > 0 && h->Elems[i / 2] > x; i /= 2)
            {
                h->Elems[i] = h->Elems[i / 2];
            }
            h->Elems[i] = x;
        }
        T deleteMin()
        {
            size_t i, child;
            T minElems, lastElems;
            if (isEmpty())
                return h->Elems[0];
            minElems = h->Elems[1];
            lastElems = h->Elems[h->size--];
            for (i = 1; i * 2 <= h->size; i = child)
            {
                child = i * 2;
                if (child != h->size && h->Elems[child + 1] < h->Elems[child])
                    ++child;
                if (lastElems > h->Elems[child])
                    h->Elems[i] = h->Elems[child];
                else
                    break;
            }
            h->Elems[i] = lastElems;
            return minElems;
        }
        bool isFull()
        {
            return h->size == h->Capacity;
        }
        bool isEmpty()
        {
            return h->size == 0;
        }
        T findMin()
        {
            return h->Elems[1];
        }
    
      private:
        void destroy()
        {
            delete h->Elems;
            delete h;
        }
        void makeEmpty() {}
    
        struct HeapStruct
        {
            size_t Capacity;
            size_t size;
            T *Elems;
        };
        HeapStruct* h;
    };
    
  • 相关阅读:
    使用NUnit做单元测试(总结版)
    http、ajax调试利器:Fiddler!!!(资料汇总)
    驳《从团购网站看中国人的创新精神》
    破解迷团:在asp.net  2.0服务器上运行.net 3.5(一)
    扩充NetCMS的功能:添加{TM:Repeater}{/TM:Repeater}标签
    TFS 2010 基础配置手动升级到高级配置 安装实践
    .net 中的 StringBuilder 和 TextWriter 区别
    最大团问题
    全排列问题
    ado.net连接池
  • 原文地址:https://www.cnblogs.com/kwebi/p/9811990.html
Copyright © 2020-2023  润新知