文章目录
(一)deque 双端队列容器
deque 双端队列容器与 vector 一样,采用线性表顺序存储结构。但与 vector 唯一不同的是,deque 采用分块的线性存储结构来存储数据,每块的大小一般为 512 字节,称为一个 deque 块,所有的 deque 块使用一个 Map 块进行管理,每个 Map 数据项记录各个 deque块的首地址。这样一来,deque 块在头部和尾部都可插入和删除元素,而不需移动其他元素(使用 push_back()方法在尾部插入元素,会扩张队列;而使用 push_front()方法在首部插入元素和使用 insert()方法在中间插入元素,只是将原位置上的元素值覆盖,不会增加新元素)。一般来说,当考虑到容器元素的内存分配策略和操作的性能时,deque 相对于 vector更有优势。双端队列容器结构示意图如图 2-6 所示。
使用 deque 需要声明头文件包含“#include ”,文件 deque 在 C:\Program
Files\Microsoft Visual Studio\VC98\Include 文件夹中。
1) 创建 deque 对象
创建 deque 对象的方法通常有三种。
(1)创建没有任何元素的 deque 对象,如:
deque d;
deque dd;
(2)创建具有 n 个元素的 deque 对象,如:
deque d(10);//创建具有 10 个整型元素的 deque 对象 d
(3)创建具有 n 个元素的 deque 对象,并赋初值,如:
deque d(10,8.5);//创建具有 10 个整型元素的 deque 对象 d,每个元素值为 8.5
2) 插入元素
(1)使用 push_back()方法从尾部插入元素,会不断扩张队列。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入三个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
//以数组方式输出元素
cout<<d[0]<<" "<<d[1]<<" "<<d[2]<<endl;
return 0;
}
运行结果:
1 2 3
(2)从头部插入元素,不会增加新元素,只将原有的元素覆盖。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入三个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
//从头部插入元素,不会增加新元素,只将原有的元素覆盖
d.push_front(10);
d.push_front(20);
//以数组方式输出元素
cout<<d[0]<<" "<<d[1]<<" "<<d[2]<<endl;
return 0;
}
运行结果:
20 10 1
(3)从中间插入元素,不会增加新元素,只将原有的元素覆盖。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入三个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
//中间插入元素,不会增加新元素,只将原有的元素覆盖
d.insert(d.begin()+1,88);
//以数组方式输出元素
cout<<d[0]<<" "<<d[1]<<" "<<d[2]<<endl;
return 0;
}
运行结果:
1 88 2
3) 遍历
- 前向遍历
(1)以数组方式遍历。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入三个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
//以数组方式输出元素
int i;
for(i=0;i<d.size();i++)
{
cout<<d[i]<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
1 2 3
2)以前向迭代器的方式遍历。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入三个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
//以前向迭代器的方式遍历
deque<int>::iterator it;
for(it=d.begin();it!=d.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
1 2 3
- 反向遍历
采用反向迭代器对双端队列容器进行反向遍历。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入三个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
//以反向迭代器的方式遍历
deque<int>::reverse_iterator rit;
for(rit=d.rbegin();rit!=d.rend();rit++)
{
cout<<*rit<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
3 2 1
4)删除元素
可以从双端队列容器的首部、尾部、中部删除元素,并可以清空双端队列容器。下面
分别举例说明这 4 种删除元素的操作方法。
(1)采用 pop_front()方法从头部删除元素。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入五个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
//从头部删除元素
d.pop_front();
d.pop_front();
//以前向迭代器的方式遍历
deque<int>::iterator it;
for(it=d.begin();it!=d.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
3 4 5
(2)采用 pop_back()方法从尾部删除元素。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入五个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
//从尾部删除元素
d.pop_back();
//以前向迭代器的方式遍历
deque<int>::iterator it;
for(it=d.begin();it!=d.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
1 2 3 4
(3)使用 erase()方法从中间删除元素,其参数是迭代器位置。
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入五个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
//从中间删除元素,erase 的参数是迭代器位置
d.erase(d.begin()+1);
//以前向迭代器的方式遍历
deque<int>::iterator it;
for(it=d.begin();it!=d.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
1 3 4 5
(4)使用 clear()方法清空 deque 对象
#include <deque>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义 deque 对象,元素类型是整型
deque<int> d;
//从尾部连续插入五个元素
d.push_back(1);
d.push_back(2);
d.push_back(3);
d.push_back(4);
d.push_back(5);
//清空元素
d.clear();
//输出元素的个数
cout<<d.size()<<endl;
return 0;
}
运行结果:
0
(二) list 双向链表容器
list 容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入、删除和查找都是极快速的。图 2-7 是 list采用的双向循环链表的结构示意图。
list 的每个节点有三个域:前驱元素指针域、数据域和后继元素指针域。前驱元素指针域保存了前驱元素的首地址;数据域则是本节点的数据;后继元素指针域则保存了后继元素的首地址。list 的头节点的前驱元素指针域保存的是链表中尾元素的首地址,而 list 的尾节点的后继元素指针域则保存了头节点的首地址,这样,就构成了一个双向循环链。由于 list 对象的节点并不要求在一段连续的内存中,所以,对于迭代器,只能通过“++”或“- -”的操作将迭代器移动到后继/前驱节点元素处。而不能对迭代器进行+n 或-n 的操作,这点,是与 vector 等不同的地方。使用 list 需要声明头文件包含“#include ”,list 文件在 C:\Program Files\MicrosoftVisual Studio\VC98\Include 文件夹中。
1) 创建 list 对象
1)创建空链表,如:
list l;
2)创建具有 n 个元素的链表,如:
list l(10); //创建具有 10 个元素的链表
2) 元素插入和遍历
有三种方法往链表里插入新元素:
(1)采用 push_back()方法往尾部插入新元素,链表自动扩张。
(2)采用 push_front()方法往首部插入新元素,链表自动扩张。
(3)采用 insert()方法往迭代器位置处插入新元素,链表自动扩张。注意,迭代器只能进行“++”或“–”操作,不能进行+n 或-n 的操作,因为元素的位置并不是物理相连的。采用前向迭代器 iterator 对链表进行遍历。
下面的程序详细说明了如何对 list 进行元素插入和遍历
#include <list>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(1);
l.push_back(5);
//在链表头部插入新元素,链表自动扩张
l.push_front(8);
//在任意位置插入新元素,链表自动扩张
list<int>::iterator it;
it=l.begin();
it++;//注意,链表的迭代器只能进行++或--操作,而不能进行+n 操作
l.insert(it,20);
//使用前向迭代器遍历链表
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
8 20 2 1 5
2)反向遍历
采用反向迭代器 reverse_iterator 对链表进行反向遍历。
#include <list>
#include <iostream>
4using namespace std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(1);
l.push_back(5);
//反向遍历链表
list<int>::reverse_iterator rit;
for(rit=l.rbegin();rit!=l.rend();rit++)
{
cout<<*rit<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
5 1 2
3) 元素删除
1)可以使用 remove()方法删除链表中一个元素,值相同的元素都会被删除。
#include <list>
#include <iostream>
using namespace std;
int main0028int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(1);
l.push_back(5);
l.push_back(1);
//遍历链表
list<int>::iterator it;
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
//删除值等于 1 的所有元素
l.remove(1);
//遍历链表
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果
2 1 5 1
2 5
2)使用 pop_front()方法删除链表首元素,使用 pop_back()方法删除链表尾元素。
#include <list>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(8);
l.push_back(1);
l.push_back(5);
l.push_back(1);
//遍历链表
list<int>::iterator it;
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
//删除首元素
l.pop_front();
//删除尾元素
l.pop_back();
//遍历链表
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
2 8 1 5 1
8 1 5
3)使用 erase()方法删除迭代器位置上的元素。
#include <list>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(8);
l.push_back(1);
l.push_back(5);
l.push_back(1);
//遍历链表
list<int>::iterator it;
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
//删除第 2 个元素(从 0 开始计数)
it=l.begin();
it++;
it++;
l.erase(it);
//遍历链表
for(it=l.begin();it!=l.e
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
2 8 1 5 1
2 8 5 1
4)使用 clear()方法清空链表。
#include <list>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(8);
l.push_back(1);
l.push_back(5);
l.push_back(1);
//遍历链表
list<int>::iterator it,it2;
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
//清空链表
l.clear();
//打印链表元素个数
cout<<l.size()<<endl;
return 0;
}
运行结果:
2 8 1 5 1
0
4) 元素查找
采用 find()查找算法可以在链表中查找元素,如果找到该元素,返回的是该元素的迭
代器位置;如果没有找到,则返回 end()迭代器位置
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(8);
l.push_back(1);
l.push_back(5);
l.push_back(1);
//遍历链表
list<int>::iterator it,it2;
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
//采用 find()查找算法在链表中查找
it=find(l.begin(),l.end(),5);
if(it!=l.end())//找到
{
cout<<"find it"<<endl;
}
else
{
cout<<"not find it"<<endl;
}
it=find(l.begin(),l.end(),10);
if(it!=l.end())//找到
{
cout<<"find it"<<endl;
}
else
{
cout<<"not find it"<<endl;
}
return 0;
}
运行结果:
2 8 1 5 1
find it
not find it
- 元素排序
采用 sort()方法可以对链表元素进行升序排列。
#include <list>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(8);
l.push_back(1);
l.push_back(5);
l.push_back(1);
//遍历链表
list<int>::iterator it,it2;
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
//使用 sort()方法对链表排序,是升序排列
l.sort();
//遍历链表
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
2 8 1 5 1
1 1 2 5 8
- 剔除连续重复元素
采用 unique()方法可以剔除连续重复元素,只保留一个。
#include <list>
#include <iostream>
using namespa4ce std;
int main(int argc, char* argv[])
{
//定义元素为整型的 list 对象,当前没有元素
list<int> l;
//在链表尾部插入新元素,链表自动扩张
l.push_back(2);
l.push_back(8);
l.push_back(1);
l.push_back(1);
l.push_back(1);
l.push_back(5);
l.push_back(1);
//遍历链表
list<int>::iterator it,it2;
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
//剔除连续重复元素(只保留一个)
l.unique();
//遍历链表
for(it=l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
2 8 1 1 1 5 1
2 8 1 5 1
(三)bitset 位集合容器
bitset 容器是一个 bit 位元素的序列容器,每个元素只占一个 bit 位,取值为 0 或 1,因而很节省内存空间。图 2-8 是一个 bitset 的存储示意图,它的 10 个元素只使用了两个字节的空间。
使用 bitset,需要声明头文件包含语句“#include ”,bitset 文件在 C:\Program
Files\Microsoft Visual Studio\VC98\Include 文件夹下。
1) 创建 bitset 对象
创建 bitset 对象时,必须要指定容器的大小。bitset 对象的大小一经定义,就不能修改了。
下面这条语句就定义了 bitset 对象 b,它能容纳 100 000 个元素,即 100 000 个 bit (位),
此时,所有元素的值都为 0。
bitset<100000> b
2) 设置元素值
1)采用下标法。
#include <bitset>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
bitset<10> b;
//采用下标法给元素赋值
b[1]=1;
b[6]=1;
b[9]=1;
//下标法输出所有元素,第 0 位是最低位,第 9 位是最高位
int i;
for(i=b.size()-1;i>=0;i--)
{
cout<<b[i];
}
cout<<endl;
return 0;
}
运行结果:
1001000010
2)采用 set()方法,一次性将元素设置为 1。
#include <bitset>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
bitset<10> b;
//采用 set()方法,一次性将元素设置为 1
b.set();
//下标法输出所有元素,第 0 位是最低位,第 9 位是最高位
int i;
for(i=b.size()-1;i>=0;i--)
{
cout<<b[i];
}
cout<<endl;
return 0;
}
运行结果:
1111111111
3)采用 set(pos)方法,将某 pos 位设置为 1。
#include <bitset>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
bitset<10> b;
//采用 set(pos)方法,将元素设置为 1
b.set(1,1);
b.set(6,1);
b.set(9,1);
//下标法输出所有元素,第 0 位是最低位,第 9 位是最高位
int i;
for(i=b.size()-1;i>=0;i--)
{
cout<<b[i];
}
cout<<endl;
return 0;
}
运行结果:
1001000010
4)采用 reset(pos)方法,将某 pos 位设置为 0。
#include <bitset>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
bitset<10> b;
//采用 set()方法,将元素全部设置为 1
b.set();
//采用 reset(pos)方法,将元素设置为 0
b.reset(0);
b.reset(2);
b.reset(3);
b.reset(4);
b.reset(5);
b.reset(7);
b.reset(8);
//下标法输出所有元素,第 0 位是最低位,第 9 位是最高位
int i;
for(i=b.size()-1;i>=0;i--)
{
cout<<b[i];
}
cout<<endl;
return 0;
}
运行结果:
1001000010
3) 输出元素
1)采用下标法输出元素。
#include <bitset>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
bitset<10> b;
//采用 set()方法,将元素全部设置为 1
b.set();
//采用 set(pos)方法,将元素设置为 0
b.set(0,0);
b.set(2,0);
b.set(3,0);
b.set(4,0);
b.set(5,0);
b.set(7,0);
b.set(8,0);
//下标法输出所有元素,第 0 位是最低位,第 9 位是最高位
int i;
for(i=b.size()-1;i>=0;i--)
{
cout<<b[i];
}
cout<<endl;
return 0;
}
运行结果:
1001000010
2)直接向输出流输出全部元素。
#include <bitset>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
bitset<10> b;
//采用 set()方法,将元素全部设置为 1
b.set();
//采用 set(pos)方法,将元素设置为 0
b.set(0,0);
b.set(2,0);
b.set(3,0);
b.set(4,0);
b.set(5,0);
b.set(7,0);
b.set(8,0);
//直接向输出流输出全部元素
cout<<b<<endl;
return 0;
}
运行结果:
1001000010
(四)stack 堆栈容器
stack 堆栈是一个后进先出(Last In First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行。插入元素的一端称为栈顶(Stack Top),而另一端则称为栈底(StackBottom)。插入元素叫入栈(Push),元素的删除则称为出栈(Pop)。图2-9 是堆栈示意图。
要使用 stack,必须声明头文件包含语句“#include ”。stack 文件在 C:\Program
Files\Microsoft Visual Studio\VC98\Include 文件夹中。
堆栈的使用方法
堆栈只提供入栈、出栈、栈顶元素访问和判断是否为空等几种方法。
采用 push()方法将元素入栈;采用 pop()方法出栈;采用 top()方法访问栈顶元素;采用empty()方法判断堆栈是否为空,如果是空的,则返回逻辑真,否则返回逻辑假。当然,可以采用 size()方法返回当前堆栈中有几个元素。
下面的程序是对堆栈各种方法的示例:
#include <stack>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义堆栈 s,其元素类型是整型
stack<int> s;
//元素入栈
s.push(1);
s.push(2);
s.push(3);
s.push(9);
//读取栈顶元素
cout<<s.top()<<endl;
//返回堆栈元素数量
cout<<s.size()<<endl;
//判断堆栈是否为空
cout<<s.empty()<<endl;
//所有元素出栈(删除所有元素)
while(s.empty()!=true)//堆栈非空
{
cout<<s.top()<<" ";//读取栈顶元素
s.pop();//出栈(即删除栈顶元素)
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
9
4
0
9 3 2 1
(五) queue 队列容器
queue 队列容器是一个先进先出(First In First Out,FIFO)的线性存储表,元素的插入只能在队尾,元素的删除只能在队首。图 2-10 是 queue 队列容器数据结构示意图。
使用 queue 需要声明头文件包含语句“#include ”,queue 文件在 C:\Program
Files\Microsoft Visual Studio\VC98\Include 文件夹里。
queue 队列的使用方法
queue 队列具有入队 push()(即插入元素)、出队 pop()(即删除元素)、读取队首元素 front()、读取队尾元素 back()、判断队列是否为空 empty()和队列当前元素的数目 size()这几种方法。
下面的程序详细说明了 queue 队列的使用方法:
#include <queue>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定义队列,元素类型是整型
queue<int> q;
//入队,即插入元素
q.push(1);
q.push(2);
q.push(3);
q.push(9);
//返回队列元素数量
cout<<q.size()<<endl;
//队列是否为空,是空,则返回逻辑真,否则返回逻辑假
cout<<q.empty()<<endl;
//读取队首元素
cout<<q.front()<<endl;
//读取队尾元素
cout<<q.back()<<endl;
//所有的元素出列(删除所有元素)
while(q.empty()!=true)
{
cout<<q.front()<<" ";
//队首元素出队(删除队首元素)
q.pop();
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
4
0
1
9
1 2 3 9
(六) priority_queue 优先队列容器
priority_queue 优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认为按元素的值由大到小排序;当然,可以重载“<”操作符来重新定义比较规则。
使用 priority_queue 需要声明头文件包含语句“#include ”,它与 queue 队列共
用一个头文件,queue 文件在 C:\Program Files\Microsoft Visual Studio\VC98\Include 文件
夹中。
1) 优先队列的使用方法
优先队列包含入队 push()(插入元素)、出队 pop()(删除元素)、读取队首元素 top()、判断队列是否为空 empty()和读取队列元素数量 size()等方法。下面这个程序详细说明了优先队列的使用方法:
#include <queue>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//定优先队列,元素类型为整型
priority_queue<int> pq;
//入队,插入新元素
pq.push(1);
pq.push(2);
pq.push(3);
pq.push(9);
//返回队列中元素数目
cout<<pq.size()<<endl;
//所有元素出队,删除所有元素
while(pq.empty()!=true)
{
//读取当前队首元素
cout<<pq.top()<<" ";
//出队,删除队首元素
pq.pop();
}
//回车换行
cout<<endl;
return 0;
}
运行结果:
4
9 3 2 1
- 重载“<”操作符来定义优先级
如果优先队列的元素类型是结构体,可以通过在结构体中重载“<”操作符的方法来修改优先队列的优先性。
#include <queue>
#include <string>
#include <iostream>
using namespace std;
//定义结构体
struct Info{
string name;
float score;
//重载“<”操作符,指定优先规则(排序规则)
bool operator < (const Info &a) const
{
//按 score 由小到大排列。如果要由大到小排列,使用“>”号即可
return a.score<score;
}
};
int main(int argc, char* argv[])
{
//定义优先队列,元素类型为 Info 结构体
priority_queue<Info> pq;
//定义结构体变量
Info info;
//入队
info.name="Jack";
info.score=68.5;
pq.push(info);
info.name="Bomi";
info.score=18.5;
pq.push(info);
info.name="Peti";
info.score=90;
pq.push(info);
//元素全部出队
while(pq.empty()!=true)
{
//返回队首元素
cout<<pq.top().name<<" : "<<pq.top().score<<endl;
//出队,删除队首元素
pq.pop();
}
return 0;
}
运行结果:
Bomi : 18.5
Jack : 68.5
Peti : 90
- 重载“()”操作符来定义优先级
如果优先队列的元素不是结构体类型,则可以通过重载“()”操作符的方式来定义优
先级。当然,元素是结构体类型,也可以通过重载“()”操作符的方式来定义优先级,而
不是一定要在结构体内重载“<”操作符才行。
下面这个程序说明了如何重载“()”操作符:
#include <queue>
#include <vector>
#include <iostream>
using namespace std;
//重载“()”操作符
struct myComp
{
bool operator()(const int &a,const int &b)
{
//由小到大排列采用“>”号;如果要由大到小排列,则采用“<”号
return a>b;
}
};
int main(int argc, char* argv[])
{
//定义优先队列,元素类型为 Info 结构体,显式说明内部结构是 vector
priority_queue<int,vector<int>,myComp> pq;
//入队
pq.push(1);
pq.push(9);
pq.push(2);
pq.push(30);
//元素全部出队
while(pq.empty()!=true)
{
//返回队首元素
cout<<pq.top()<<" ";
//出队,删除队首元素
pq.pop();
}
cout<<endl;
return 0;
}
运行结果:
1 2 9 30
)
{
//定义优先队列,元素类型为 Info 结构体
priority_queue pq;
//定义结构体变量
Info info;
//入队
info.name=“Jack”;
info.score=68.5;
pq.push(info);
info.name=“Bomi”;
info.score=18.5;
pq.push(info);
info.name=“Peti”;
info.score=90;
pq.push(info);
//元素全部出队
while(pq.empty()!=true)
{
//返回队首元素
cout<<pq.top().name<<" : "<<pq.top().score<<endl;
//出队,删除队首元素
pq.pop();
}
return 0;
}
运行结果:
Bomi : 18.5
Jack : 68.5
Peti : 90
3) 重载“()”操作符来定义优先级
如果优先队列的元素不是结构体类型,则可以通过重载“()”操作符的方式来定义优
先级。当然,元素是结构体类型,也可以通过重载“()”操作符的方式来定义优先级,而
不是一定要在结构体内重载“<”操作符才行。
下面这个程序说明了如何重载“()”操作符:
```c++
#include <queue>
#include <vector>
#include <iostream>
using namespace std;
//重载“()”操作符
struct myComp
{
bool operator()(const int &a,const int &b)
{
//由小到大排列采用“>”号;如果要由大到小排列,则采用“<”号
return a>b;
}
};
int main(int argc, char* argv[])
{
//定义优先队列,元素类型为 Info 结构体,显式说明内部结构是 vector
priority_queue<int,vector<int>,myComp> pq;
//入队
pq.push(1);
pq.push(9);
pq.push(2);
pq.push(30);
//元素全部出队
while(pq.empty()!=true)
{
//返回队首元素
cout<<pq.top()<<" ";
//出队,删除队首元素
pq.pop();
}
cout<<endl;
return 0;
}
运行结果:
1 2 9 30