C++常用数据结构

C++常用数据类型

  1. string
    geeksforgeeks-string


C++常用STL容器

oi-wiki:STL容器

序列式容器

  1. vector
    geeksforgeeks-vector

  2. queue
    geeksforgeeks-queue

  3. stack
    geekdorgeeks-stack
    C++中的stack是一种容器适配器,用于表示后进先出(LIFO,Last In First Out)数据结构。它提供了一组函数来操作一系列元素,具有如下特点和方法:

  • 主要特点
    后进先出(LIFO): stack只允许在容器的一端插入和删除元素,这一端被称为栈顶(top)。
    容器适配器: stack不是一种独立的容器,而是基于其他容器(如deque,vector或list)实现的适配器。默认情况下,stack使用deque作为底层容器。
    std::stack<int> stack1; // 默认构造函数,使用deque作为底层容器
    std::stack<int, std::vector<int>> stack2; // 使用vector作为底层容器
    push(): 向栈顶添加元素。
    
    stack1.push(10); // 将10压入栈顶
    pop(): 移除栈顶元素。该操作不会返回被移除的元素。
    
    stack1.pop(); // 移除栈顶元素
    top(): 返回栈顶元素的引用。
    
    int topElement = stack1.top(); // 获取栈顶元素
    empty(): 检查栈是否为空。
    
    bool isEmpty = stack1.empty(); // 如果栈为空,返回true
    size(): 返回栈中元素的数量。
    
    size_t size = stack1.size(); // 获取栈中元素数量
    

关联式容器(associative container)

分有序和无序

  1. unordered_map
    geeksforgeeks-unorderedmap

  2. set
    geeksforgeeks-set

  3. priority_queue
    堆,heap
    geeksforgeeks-priority_queue

优先级队列的比较函数:在C++中,priority_queue的比较函数通常是一个二元谓词,它应该是一个函数或者函数对象,接受两个参数,返回一个bool值。这里的比较函数cmp是一个成员函数,它不符合这个要求。你要么需要将cmp函数定义为静态的,要么使用一个比较函数对象。

理解自定义比较函数对象中的 a > b 可以通过以下解释:

优先级队列和比较函数

std::priority_queue 是一个基于堆的数据结构。它使用一个比较函数来决定元素的顺序。默认情况下,C++ 标准库使用 std::less<T> 作为比较函数,这意味着它是一个最大堆,即最大的元素在堆顶。

自定义比较函数对象

当我们想要改变这个行为,例如希望最小的元素在堆顶,我们需要提供一个自定义的比较函数。

自定义比较函数的工作原理

比较函数决定了堆中元素的优先级。对于最大堆,比较函数是 std::less<T>,即 a < b,这样较大的元素会被放在堆顶。为了将 std::priority_queue 转变为最小堆,我们需要反转这个比较逻辑,使较小的元素被放在堆顶。

为什么使用 a > b

当我们使用 a > b 作为比较函数时,实际上是在定义一个“较小”的优先级较高的队列。在比较两个元素 ab 时:

  • 如果 ab 大,即 a > b 返回 true,则 a 的优先级较低,被放置在堆的更下面。
  • 如果 ab 小,即 a > b 返回 false,则 a 的优先级较高,被放置在堆的更上面。

这样,最终较小的元素会被放在堆顶,从而实现最小堆的效果。

代码示例

以下是自定义比较函数对象的实现及其用法:

#include <iostream>
#include <queue>
#include <vector>

// 自定义比较函数对象
// 如果这里是class,需要使用public声明
struct Compare {
    bool operator()(int a, int b) {
        return a > b; // 使最小值在顶部
    }
};

int main() {
    std::priority_queue<int, std::vector<int>, Compare> pq; // 最小堆
    pq.push(3);
    pq.push(1);
    pq.push(4);
    pq.push(1);
    pq.push(5);
    pq.push(9);

    while (!pq.empty()) {
        std::cout << pq.top() << " ";
        pq.pop();
    }

    return 0;
}

输出解释

输出将是 1 1 3 4 5 9。这是因为我们使用了 a > b 作为比较函数,使得较小的元素有较高的优先级,被放在堆顶。

重点总结

  • std::priority_queue 默认是最大堆。
  • 通过自定义比较函数 a > b,我们定义了较小的元素优先级更高,变成最小堆。
  • 这种方式可以灵活地改变优先级队列的行为,以满足不同的需求。
posted @ 2023-12-16 22:43  walkallday  阅读(46)  评论(0)    收藏  举报