队列 std::queue 双端队列 std::deque,优先级队列 std::priorty_queue

一、双端队列 std::deque

中文标准库:std::deque

转载:STL源码剖析——deque的实现原理和使用方法详解

vector

sizeof(deque)

std::deque(double-ended queue)双端队列,是有下标的顺序容器。它允许在其首尾两端快速插入及删除。另外,在deque任一端插入或删除不会非法化指向其余元素的指针或引用(例如vector删除第一个元素,其他所有迭代器的值都会指向下一个元素,而deque删除后指向元素为空)

与std::vector相反,deque 的元素不是连续存储的,典型实现:用单独分配的固定大小数组的序列,外加额外的登记,这表示下标访问必须进行二次指针解引用,与之相比vector的下标访问只进行一次。

deque的存储按需自动扩展及收缩。扩张deque比扩张std::vector更优,因为它不涉及复制既存元素到新内存位置。另一方面,deque典型地拥有较大的最小内存开销;只有一个元素的deque必须分配其整个内部数组。

1.构造

std::deque<int> d1{ 1,2,3,4,5 }; //d1 = 1,2,3,4,5
std::deque<int> d2(3, 5);  //d2 = 5,5,5
std::deque<int> d3(d1.begin(), d1.begin() + 2); //d3 = 1,2

2.添加

	d2.emplace(d2.begin() + 1, 2); //开始的下一个位置添加一个2:5,2,5,5
	d2.emplace_back(3);  //末尾添加一个3:5,2,5,5,3
	d2.emplace_front(4); //首部添加一个4:4,5,2,5,5,3

	d2.push_back(6);     //末尾添加一个6:{4,5,2,5,5,3,6}
	d2.insert(d2.end(), 1);//末尾添加一个1:{4,5,2,5,5,3,6,1}
	d2.insert(d2.begin(), { 7,8,9 }); //首部添加一组7,8,9:{7,8,9,4,5,2,5,5,3,6,1}

3.访问

	auto ret1 = d2.front();
	auto ret2 = d2.back();
	auto ret3 = *d2.begin();
	auto ret4 = d2[5];   //从0开始第5个
	auto ret5 = d2.at(2);//从0开始第2个

	//auto r1 = d2.at(100); //崩溃
	//auto r2 = d2[100];    //中断

4.删除

	d2.pop_back(); //移除最后一个元素
	d2.pop_front();//移除第一个元素
	d2.erase(d2.begin());//移除指定位置的一个元素(移除第一个元素)
	d2.erase(d2.begin(), d2.begin() + 2); //移除指定范围的n个元素(移除前两个元素)
	d2.clear();//清空元素

5.其他

函数 描述
empty() deque为空返回true
size() 返回deuqe元素的个数
swap(deque&) 交换两个deque的元素
resize(size_t) 设置deque的元素个数
max_size() 返回deuqe可容纳的最大元素个数

示例代码

点击查看代码
#include <list>
#include <deque>

int main()
{
	std::deque<int> d1{ 1,2,3,4,5 }; //d1 = 1,2,3,4,5
	std::deque<int> d2(3, 5);  //d2 = 5,5,5
	std::deque<int> d3(d1.begin(), d1.begin() + 2); //d3 = 1,2


	d2.emplace(d2.begin() + 1, 2); //开始的下一个位置添加一个2:5,2,5,5
	d2.emplace_back(3);  //末尾添加一个3:5,2,5,5,3
	d2.emplace_front(4); //首部添加一个4:4,5,2,5,5,3

	d2.push_back(6);     //末尾添加一个6:{4,5,2,5,5,3,6}
	d2.insert(d2.end(), 1);//末尾添加一个1:{4,5,2,5,5,3,6,1}
	d2.insert(d2.begin(), { 7,8,9 }); //首部添加一组7,8,9:{7,8,9,4,5,2,5,5,3,6,1}

	auto ret1 = d2.front();
	auto ret2 = d2.back();
	auto ret3 = *d2.begin();
	auto ret4 = d2[5];   //从0开始第5个
	auto ret5 = d2.at(2);//从0开始第2个

	//auto r1 = d2.at(100); //崩溃
	//auto r2 = d2[100];    //中断

	d2.pop_back(); //移除最后一个元素
	d2.pop_front();//移除第一个元素
	d2.erase(d2.begin());//移除指定位置的一个元素(移除第一个元素)
	d2.erase(d2.begin(), d2.begin() + 2); //移除指定范围的n个元素(移除前两个元素)
	d2.clear();//清空元素
	

	int test = 0;
	return 0;
}

二、队列 std::queue

先进先出,只能队尾插入元素,队首抛出元素

中文标准库:std::queue

点击查看代码
#include <queue>

int main()
{
	std::queue<int> myQueue({ 1, 2, 3 });
	myQueue.emplace(4); // 队尾添加一个元素
	myQueue.push(5);    // 队尾添加一个元素
	myQueue.pop();      // 抛出队首元素
	auto ret1 = myQueue.empty();    // 判断是否为空
	auto ret2 = myQueue.size();     // 元素个数
	std::deque<int> myDeque{ 2,3,4 };
	std::queue<int> myQueue1(myDeque);
	myQueue.swap(myQueue1);// 交换元素

	int test = 0;
}

三、优先级队列 std::priorty_queue

中文标准库:priorty_queue

要想对自定义数据结构使用优先级队列必须实现对“<”的重载

优先级队列有三个比较重要的成员函数

函数 描述
push(const value_type& value) 队列尾部添加一个元素
top() 返回权值最大(或最小)的元素
pop() 删除权值最大(或最小)的元素,即删除top()元素,注意:此处不是队首元素

示例代码

点击查看代码
#include <iostream>
#include <queue>
#include <map>

class A
{
public:
    A(int x) { a = x; }
    int a;
    bool operator < (const A& aa) const  //后置const必须有
    {
        return aa.a < this->a;
    }
};

int main()
{
    std::priority_queue<A> p3;

    p3.emplace(A(1));
    p3.emplace(A(5));
    p3.emplace(A(2));
    p3.emplace(A(9));
    p3.emplace(A(4));
    p3.emplace(A(3));

    while (!p3.empty())
    {
        std::cout << p3.top().a << "\n";
        p3.pop();
    }

    std::cout << "========\n";

    std::priority_queue<std::pair<int, int>> p2;  //按pair的first排序

    p2.emplace(1, 1);
    p2.emplace(3, 3);
    p2.emplace(7, 7);
    p2.emplace(8, 2);
    p2.emplace(5, 9);

    while (!p2.empty())
    {
        std::cout << p2.top().first << " " << p2.top().second << "\n";
        p2.pop();
    }

    return 0;
}
posted @ 2021-09-24 17:01  滴哒哒哒  阅读(1096)  评论(0编辑  收藏  举报