栈与队列?

1.stack  先进后出

  1.1常见函数 :top empty size push pop

力扣

2.queue   先进先出

力扣

    2.1常见函数 :front back empty size push pop 

3.Deque

在C++中,deque容器(双端队列)提供了许多成员函数,用于在双端队列中插入、删除、访问和操作元素。下面是一些deque常见的函数:

  1. push_back():将元素插入双端队列的末尾。

  2. push_front():将元素插入双端队列的开头。

  3. pop_back():从双端队列的末尾删除一个元素。

  4. pop_front():从双端队列的开头删除一个元素。

  5. size():返回双端队列中元素的个数。

  6. empty():检查双端队列是否为空。

  7. clear():删除双端队列中的所有元素。

  8. back():返回双端队列中的最后一个元素的引用。

  9. front():返回双端队列中的第一个元素的引用。

  10. at(index):返回双端队列中指定索引位置的元素的引用。与operator[]不同,at()会进行边界检查,并在索引越界时抛出std::out_of_range异常。

  11. begin():返回指向双端队列第一个元素的迭代器。

  12. end():返回指向双端队列最后一个元素后面位置的迭代器(尾后迭代器)。

  13. rbegin():返回指向双端队列最后一个元素的反向迭代器。

  14. rend():返回指向双端队列第一个元素前面位置的反向迭代器(逆尾后迭代器)。

  15. insert(pos, value):在指定位置之前插入一个元素。

  16. erase(pos):删除指定位置的元素。

  17. erase(first, last):删除指定范围内的元素。

  18. swap(other):将双端队列与另一个双端队列进行交换。

这些是deque容器中的一些常用函数。使用这些函数,可以方便地对双端队列进行插入、删除、访问和操作。注意,deque还继承了vector的一部分函数,因此一些vector的函数也可以在deque中使用。要使用deque,请包含<deque>头文件

#include <iostream> #include <deque> int main() { std::deque<std::string> words; // 使用emplace函数就地构造新元素并插入到deque中 words.emplace(words.begin(), "Hello"); words.emplace_back("World"); // 遍历输出deque中的元素 for (const auto& word : words) { std::cout << word << " "; } std::cout << std::endl; return 0; }

priority_queue 是 C++ STL 提供的一个容器适配器(Container Adapter),用于实现优先队列(Priority Queue)。优先队列是一种特殊的队列,其中的元素按照一定的优先级进行排序,具有较高优先级的元素排在队列的前面。

常见的 priority_queue 函数如下:

  1. 构造函数

    • priority_queue(): 创建一个空的优先队列。
    • priority_queue(const Compare& cmp): 使用自定义的比较函数 cmp 创建一个空的优先队列。
    • priority_queue(const Container& cont): 使用容器 cont 中的元素创建一个优先队列。
    • priority_queue(const Container& cont, const Compare& cmp): 使用容器 cont 中的元素和自定义的比较函数 cmp 创建一个优先队列。
  2. 修改容器

    • push(const T& value): 将 value 插入优先队列中,并根据优先级进行排序。
    • pop(): 删除队列顶部的元素,即具有最高优先级的元素。
    • emplace(Args&&... args): 就地构造一个元素,并将其插入到优先队列中。
  3. 访问元素

    • top(): 获取队列顶部的元素,即具有最高优先级的元素。
  4. 容量和状态

    • empty(): 检查队列是否为空,返回布尔值。
    • size(): 返回队列中元素的个数。

需要注意的是,priority_queue 默认使用 operator< 运算符来比较元素的优先级,即较大的元素优先级更高。如果需要自定义比较函数,可以通过提供自定义的比较函数或使用函数对象来指定排序规则。

以下是一个使用 priority_queue 的示例程序:

#include <iostream>
#include <queue>

int main() {
    std::priority_queue<int> pq;

    pq.push(30);
    pq.push(10);
    pq.push(50);

    std::cout << "Top element: " << pq.top() << std::endl; // 输出:Top element: 50

    pq.pop();

    std::cout << "Top element after pop: " << pq.top() << std::endl; // 输出:Top element after pop: 30

    std::cout << "Size of priority queue: " << pq.size() << std::endl; // 输出:Size of priority queue: 2

    return 0;
}

在上述示例中,我们使用 priority_queue 来保存整数元素,并插入了 30、10 和 50。根据默认的比较规则(operator<),较大的元素具有较高的优先级。通过 top 函数,我们获得了优先队列的顶部元素。然后,使用 pop 函数移除队列顶部的元素,并展示了队列尺寸(通过 size 函数)。

单调队列(Monotonic Queue)是一种特殊的数据结构,用于解决一类与窗口(滑动窗口)相关的算法问题。它是在队列的基础上进行了扩展和优化,可以在常数时间内获取当前窗口的最大值或最小值。

单调队列可以分为两种类型:单调递增队列和单调递减队列。单调递增队列中,队列中的元素从队首到队尾按照递增的顺序排列,而单调递减队列则相反,元素按照递减的顺序排列。

单调队列主要提供以下两个操作:

  1. push(x): 将元素 x 插入队尾,并保持队列的单调性。在插入新元素时,会将队列中小于x的元素都从队尾移除,以保持递增或递减的单调性。
  2. pop(): 移除队首元素。

通过单调队列,我们可以快速获取当前窗口的最大值或最小值。在滑动窗口问题中,我们可以使用单调队列来维护一个窗口内的最大(最小)元素,使得在窗口滑动时能够在常数时间内更新最大(最小)值,而不需要遍历窗口内的所有元素。

常见的滑动窗口问题,如找到最大滑动窗口、找到最小滑动窗口、找到滑动窗口中的最大值与最小值之差等,都可以使用单调队列解决。单调队列在时间复杂度和空间复杂度上都有较好的性能表现,因此在处理滑动窗口问题时是一种很有效的数据结构。

http://t.csdn.cn/1fTn1

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

堆 一个完全二叉树

小根堆 每个父节点元素要小于他的子节点

大根堆 每个父节点元素要大于他的子节点

存储 先层序遍历编个号 再用数组存储

节点下表为i

左子节点下标为2i+1

右子节点下标为2i+2

下滤:我们吧根节点向下调整的操作为下滤,(根节点破坏了堆序性)

上滤:和他的父节点比较(树的最后一个节点元素破坏了堆序性)用于插入新元素到堆中o(logn)

 建堆:自顶向下 将数组中的元素插入堆 然后上滤o(nlogn)

         自下而上  从倒数第二排开始对每个父节点进行下滤操作直到根节点操作完毕 o(n)

优先队列 小根堆 弹出最小元素 将最后一个元素放到根节点 然后下滤

堆排序用大根堆是正序

用小根堆是逆序

  优先级队列 :http://t.csdn.cn/tKQ3S

2.默认优先输出大数据
priority_queue<Type, Container, Functional>

其中, Type 为数据类型. Container 为保存数据的容器. Functional 为元素比较的方式.

若不写后面两个参数.

容器 默认使用 vector

比较方式 默认使用 operator < 即优先队列是大顶堆. 队头元素最大
大根堆声明方式:
大根堆就是把大的元素放在堆顶的堆。优先队列默认实现的就是大根堆,所以大根堆的声明不需要任何花花肠子,直接按C++STL的声明规则声明即可。

3.优先输出小数据 即小顶堆

  • priority_queue<int, vector<int>, greater<int> > p;
  • 使用 greater<int> . 即改用 operator >
    小根堆声明方式
    大根堆是把大的元素放堆顶,小根堆就是把小的元素放到堆顶。

priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(&cmp)> q(cmp); 解释一下这里

优先队列的模板声明如下:priority_queue <T, Container, Compare>

在这里,T 是存储在队列中的元素的类型,即 pair<int, int>,其中 int 是数组的值,另一个 int 是该值出现的次数。

Container 是用于存储队列元素的容器类型,默认情况下是 std::vector,因此我们可以简写为 priority_queue<pair<int, int>>

Compare 是一个比较函数,用于定义队列中元素的比较方式。在这里,比较函数使用了静态成员函数 cmp,其作用是比较两个 pair<int, int> 元素的第二个值(即出现次数),并按降序排序。

最后,我们使用 decltype(&cmp) 来指定 priority_queue 对象 q 使用的比较方式为静态成员函数 cmp

这样,我们就创建了一个最大堆的优先队列 q,其中元素是 pair<int, int> 类型,按照出现次数降序排序。

在使用 priority_queue 时,需要传递一个比较函数作为参数来确定优先级的顺序。在你的代码中,比较函数 cmp 是作为一个非静态成员函数进行定义的。然而,priority_queue 要求比较函数为静态成员函数或全局函数。

为解决这个问题,你可以将比较函数 cmp 定义为 static bool cmp(pair<int, int>& m, pair<int, int>& n),这样就可以满足 priority_queue 的要求。

同时,在初始化 priority_queue 时,需要指定比较函数的类型。在你的代码中,可以使用 decltype(cmp)* 来获取比较函数的指针类型作为模板参数,即 priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)*> q(cmp)

这样做的目的是确保 priority_queue 在插入元素时能够按照你定义的比较函数的规则进行排序。修复后的代码如下:

class Solution {
public:
    static bool cmp(pair<int, int>& m, pair<int, int>& n) {
        return m.second > n.second;
    }

    vector<int> topKFrequent(const vector<int>& nums, int k) {
        unordered_map<int, int> occurrences;
        for (const auto& v : nums) {
            occurrences[v]++;
        }

        // pair 的第一个元素代表数组的值,第二个元素代表了该值出现的次数
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)*> q(cmp);
        for (const auto& [num, count] : occurrences) {
            if (q.size() == k) {
                if (q.top().second < count) {
                    q.pop();
                    q.push(make_pair(num, count));
                }
            } else {
                q.push(make_pair(num, count));
            }
        }
        vector<int> ret;
        while (!q.empty()) {
            ret.push_back(q.top().first);
            q.pop();
        }
        return ret;
    }
};

这样修改后的代码应该可以正常编译和运行。非常抱歉之前的回答可能引起了困惑,感谢你的指出。如果还有任何疑问,请随时提问。

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值