C++ 遍历 queue

简短不看版

C++中的std::queue本身是不直接支持遍历操作的(通俗点讲,无法使用迭代器和下标访问)。

那么如果有这方面的需求,且操作频繁的话,最好用std::deque取代之(deque 是支持遍历操作的)。

 

C++ 遍历queue:不推荐,但可以自己搞

在C++中,std::queue是一个遵循先进先出(FIFO)原则的容器。由于std::queue不提供直接访问容器内部元素的方法,因此不能直接遍历。但是,您可以使用一个临时队列来遍历。以下是如何做到这一点的示例代码:

#include <iostream>
#include <queue>
 
int main() {
    std::queue<int> q;
 
    // 添加一些元素到队列
    for (int i = 0; i < 5; ++i) {
        q.push(i);
    }
 
    // 使用临时队列遍历
    std::queue<int> temp(q); // 复制原队列到临时队列
    while (!temp.empty()) {
        std::cout << temp.front() << " ";
        temp.pop(); // 弹出元素以遍历下一个元素
    }
    std::cout << std::endl;
 
    return 0;
}

这段代码会输出

0 1 2 3 4

请注意,这种方法会复制队列中的所有元素,如果队列很大,这可能不是最佳选择。如果需要频繁遍历队列,可以考虑使用std::deque作为底层容器,然后使用std::queue进行封装,这样可以保持队列的FIFO特性,同时提供遍历能力。

 

或者采用这种办法:

#include<iostream>
#include<queue>

using namespace std;
int main(int argc, char* argv[]) {

   queue<int> myqueue;
   myqueue.push(1);
   myqueue.push(2);
   myqueue.push(3);

   int myqueue_size = myqueue.size();
   for(int i = 0; i < myqueue_size; i++) {   //myqueue_size 必须是固定值
      cout << myqueue.front() << endl;
      myqueue.push(myqueue.front());
      myqueue.pop();
   } 
}

 

 

C++ 遍历 deque

相对于std::queue不支持遍历,std::deque是支持遍历的,遍历方法多种多样:通过迭代器、下标、for+:方法,代码如下:

#include<iostream>
#include<deque>
using namespace std;
int main()
{
	deque<int> d; //定义一个数据类型为int的deque
	d.push_back(1); //向队列中加入元素1 
	d.push_back(2); //向队列中加入元素2
	d.push_back(3); //向队列中加入元素3
	d.push_back(4); //向队列中加入元素4
	deque<int>::iterator it;
	for(it=d.begin();it!=d.end();it++)    //方法1:通过迭代器
	{
		cout<<*it<<" ";
	}
    
    for(int i=0;i<d.size();i++)           //方法2:通过下标
	{
		cout<<d[i]<<" ";
	}
    
    for(int it:d)                        //方法3: 通过 for+: 方法
	{
		cout<<it<<" ";
	}
    
}

 

 

 扩展:deque 的介绍

deque是一个双向队列(double-ended queue),可以在队列的两端进行元素的插入和删除操作。deque的全称是double-ended queue,翻译过来就是双端队列,也有人称之为双向队列,这两个名称都可以表示该数据结构。deque是C++STL(标准模板库)中的一种容器,可以用于存储各种类型的元素。deque的特点是可以在队列的两端进行元素的操作,并且可以高效地在队列的任意位置进行元素的插入和删除操作。
可以说deque几乎涵盖了queue(队列)、stack(堆栈)、vector(向量 )等的全部用法,功能非常的强大。

使用deque时需要包含头文件:

#include <deque>

deque常见的成员函数有:

push_back()//在队列的尾部插入元素。
emplace_front()//与push_front()的作用一样 
push_front()//在队列的头部插入元素。
emplace_back()//与push_back()的作用一样 
pop_back()//删除队列尾部的元素。
pop_front()//删除队列头部的元素。
back()//返回队列尾部元素的引用。
front()//返回队列头部元素的引用。
clear()//清空队列中的所有元素。
empty()//判断队列是否为空。
size()//返回队列中元素的个数。
begin()//返回头位置的迭代器
end()//返回尾+1位置的迭代器
rbegin()//返回逆头位置的迭代器 
rend()//返回逆尾-1位置的迭代器 
insert()//在指定位置插入元素 
erase()//在指定位置删除元素 

实例代码:

#include<iostream>
#include<deque>
using namespace std;
int main()
{
	deque<int> d; //定义一个数据类型为int的deque
	d.push_back(1); //向队列中加入元素1 
	d.push_back(2); //向队列中加入元素2
	d.push_back(3); //向队列中加入元素3
	d.push_back(4); //向队列中加入元素4
	cout<<"双端队列中现在的元素为:"<<endl;
	for(int i=0;i<d.size();i++)
	{
		cout<<d[i]<<" ";
	}
	cout<<endl;
	d.pop_front();
	cout<<"弹出队首元素后,双端队列中现在的元素为:"<<endl;
	for(int i=0;i<d.size();i++)
	{
		cout<<d[i]<<" ";
	}
	cout<<endl;
	d.pop_back();
	cout<<"弹出队尾元素后,双端队列中现在的元素为:"<<endl;
	for(int i=0;i<d.size();i++)
	{
		cout<<d[i]<<" ";
	}
	cout<<endl;
	d.push_back(6);
	cout<<"在队尾添加元素6后,双端队列中现在的元素为:"<<endl;
	for(int i=0;i<d.size();i++)
	{
		cout<<d[i]<<" ";
	}
	cout<<endl;
	d.push_front(8);
	cout<<"在队首添加元素8后,双端队列中现在的元素为:"<<endl;
	for(int i=0;i<d.size();i++)
	{
		cout<<d[i]<<" ";
	}
}

运行结果:

双端队列中现在的元素为:
1 2 3 4
弹出队首元素后,双端队列中现在的元素为:
2 3 4
弹出队尾元素后,双端队列中现在的元素为:
2 3
在队尾添加元素6后,双端队列中现在的元素为:
2 3 6
在队首添加元素8后,双端队列中现在的元素为:
8 2 3 6

 

deque 与vector 的对比:

 deque有很多函数和vector类似,但是deque在随机存取操作上并没有vector快,因为我们它并不是连续存储元素的。

存储机制决定了vector不适合元素的大量存储,因为它使用单一内存块,而deque可以使用多个内存块,这使得deque在存储大量元素时或者大的对象时比vector有优势。

但如果需要频繁的随机存取操作deque表现不如vector,因为vector是连续空间,随机存取很方便。

posted @ 2024-04-08 20:01  FBshark  阅读(797)  评论(0编辑  收藏  举报