Queue和Stack头文件的使用

一.首先需要说明的是,queue和stack头文件只能用在C++中。

在VC中,不支持#include<queue>和include<stack>

在其他编译器中,如codeblocks,可以选择生成C++文件

头文件的写法有:

C++

#include<iostream>

#include<cstdlib>

#include<queue>

#include<stack>

using namespace std;

或者:

C:  注:<cstdio>是C++为了兼容C而将原来C中的.h文件(如stdio.h)放入std命名空间中,改名问<cstdio>

#include<cstdio>

#include<cstdlib>

#include<queue>

#include<stack>

二.详细说明

1、stack
stack 模板类的定义在<stack>头文件中。
stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要
的,在不指定容器类型时,默认的容器类型为deque。


定义stack 对象的示例代码如下:
stack<int> s1;
stack<string> s2;


stack 的基本操作有:
s.push(x);    入栈
s.pop();        出栈,注意,出栈操作只是删除栈顶元素,并不返回该元素。
s.top();      访问栈顶元素
s.empty(), 判断栈空,当栈空时,返回true。
s.size()        访问栈中元素个数


2、queue
queue 模板类的定义在<queue>头文件中。
与stack 模板类很相似,queue 模板类也需要两个模板参数,一个是元素类型,一个容器类
型,元素类型是必要的,容器类型是可选的,默认为deque 类型。


定义queue 对象的示例代码如下:
queue<int> q1;
queue<double> q2;

queue 的基本操作有:
q.push(x);       入队, 将x 接到队列的末端。
q.pop();           出队, 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
q.front(),       访问队首元素,即最早被压入队列的元素。
q.back(),       访问队尾元素,即最后被压入队列的元素。
q.empty(),     判断队空,当队列空时,返回true。
q.size()            访问队中元素个数

看下面这个简单实例:

#include <iostream>
#include <cstdlib>
#include <queue>
#include <stack>
using namespace std;

int main()
{
    int i,j,e,n,m,s;
    queue<int> q1;
    stack<int> s1;

    cout<<"Queue test!"<<endl;

    if(q1.empty())
        cout<<"Queue Empty!"<<endl;

    for(i=0;i<10;i++)
        q1.push(i);

    if(!(q1.empty()))
        cout<<"NO Empty"<<endl;


    n=q1.size();
    cout<<"size:"<<n<<endl;

    m=q1.back();
    cout<<"Tail:"<<m<<endl;

    for(i=0;i<10;i++)
    {
        e=q1.front();
        cout<<"front:"<<e<<endl;
        q1.pop();
    }


    if(q1.empty())
        cout<<"Queue empty agagin!"<<endl;

    cout<<endl;

    cout<<"Stack test!"<<endl;

    if(s1.empty())
        cout<<"stack empty!"<<endl;

    for(i=0;i<10;i++)
        s1.push(i);

    if(!s1.empty())
        cout<<"stack not empty!"<<endl;

    n=s1.size();
    cout<<"size:"<<n<<endl;


    for(i=0;i<10;i++)
    {
        m=s1.top();
        cout<<"top:"<<m<<endl;
        s1.pop();
    }

    if(s1.empty())
        cout<<"Stack empty again!"<<endl;

    return 0;
}

运行结果:


3、priority_queue
在<queue>头文件中,还定义了另一个非常有用的模板类priority_queue(优先队列)。优先队
列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序
出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。
priority_queue 模板类有三个模板参数,第一个是元素类型,第二个容器类型,第三个是比
较算子。其中后两个都可以省略,默认容器为vector,默认算子为less,即小的往前排,大
的往后排(出队时序列尾的元素出队)。
定义priority_queue 对象的示例代码如下:
priority_queue<int> q1;
priority_queue< pair<int, int> > q2; // 注意在两个尖括号之间一定要留空格。
priority_queue<int, vector<int>, greater<int> > q3; // 定义小的先出队
priority_queue 的基本操作与queue 相同。
初学者在使用priority_queue 时,最困难的可能就是如何定义比较算子了。
如果是基本数据类型,或已定义了比较运算符的类,可以直接用STL 的less 算子和greater
算子——默认为使用less 算子,即小的往前排,大的先出队。
如果要定义自己的比较算子,方法有多种,这里介绍其中的一种:重载比较运算符。优先队
列试图将两个元素x 和y 代入比较运算符(对less 算子,调用x<y,对greater 算子,调用x>y),
若结果为真,则x 排在y 前面,y 将先于x 出队,反之,则将y 排在x 前面,x 将先出队。
看下面这个简单的示例:

#include <iostream>
#include <queue>
using namespace std;
class T
{
    public:
    int x, y, z;
    T(int a, int b, int c):x(a), y(b), z(c)
    {
    }
};
bool operator < (const T &t1, const T &t2)
{
    return t1.z < t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
}
int main()
{
    priority_queue<T> q;
    q.push(T(4,4,3));
    q.push(T(2,2,5));
    q.push(T(1,5,4));
    q.push(T(3,3,6));
    while (!q.empty())
    {
        T t = q.top(); q.pop();
        cout << t.x << " " << t.y << " " << t.z << endl;
    }
    return 1;
}
输出结果为(注意是按照z 的顺序从大到小出队的):
3 3 6
2 2 5
1 5 4
4 4 3


再看一个按照z 的顺序从小到大出队的例子:

#include <iostream>
#include <queue>
using namespace std;
class T
{
    public:
    int x, y, z;
    T(int a, int b, int c):x(a), y(b), z(c)
    {
    }   
};
bool operator > (const T &t1, const T &t2)
{
    return t1.z > t2.z;
}
int main()
{
    priority_queue<T, vector<T>, greater<T> > q;
    q.push(T(4,4,3));
    q.push(T(2,2,5));
    q.push(T(1,5,4));
    q.push(T(3,3,6));
    while (!q.empty())
    {
        T t = q.top(); q.pop();
        cout << t.x << " " << t.y << " " << t.z << endl;
    }
    return 1;
}
输出结果为:
4 4 3
1 5 4
2 2 5
3 3 6



如果我们把第一个例子中的比较运算符重载为:

bool operator < (const T &t1, const T &t2)
{
    return t1.z > t2.z; // 按照z 的顺序来决定t1 和t2 的顺序
}

则第一个例子的程序会得到和第二个例子的程序相同的输出结果。



  • 18
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C、传统 C++ #include <assert.h>    //设定插入点 #include <ctype.h>     //字符处理 #include <errno.h>     //定义错误码 #include <float.h>     //浮点数处理 #include <fstream.h>    //文件输入/输出 #include <iomanip.h>    //参数化输入/输出 #include <iostream.h>   //数据流输入/输出 #include <limits.h>    //定义各种数据类型最值常量 #include <locale.h>    //定义本地化函数 #include <math.h>     //定义数学函数 #include <stdio.h>     //定义输入/输出函数 #include <stdlib.h>    //定义杂项函数及内存分配函数 #include <string.h>    //字符串处理 #include <strstrea.h>   //基于数组的输入/输出 #include <time.h>     //定义关于时间的函数 #include <wchar.h>     //宽字符处理及输入/输出 #include <wctype.h>    //宽字符分类 ////////////////////////////////////////////////////////////////////////// 标准 C++ (同上的不再注释) #include <algorithm>    //STL 通用算法 #include <bitset>     //STL 位集容器 #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex>     //复数类 #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque>      //STL 双端队列容器 #include <exception>    //异常处理类 #include <fstream> #include <functional>   //STL 定义运算函数(代替运算符) #include <limits> #include <list>      //STL 线性列表容器 #include <map>       //STL 映射容器 #include <iomanip> #include <ios>       //基本输入/输出支持 #include <iosfwd>     //输入/输出系统使用的前置声明 #include <iostream> #include <istream>     //基本输入流 #include <ostream>     //基本输出流 #include <queue>      //STL 队列容器 #include <set>       //STL 集合容器 #include <sstream>     //基于字符串的流 #include <stack>      //STL 堆容器     #include <stdexcept>    //标准异常类 #include <streambuf>    //底层输入/输出支持 #include <string>     //字符串类 #include <utility>     //STL 通用模板类 #include <vector>     //STL 动态数组容器 #include <cwchar> #include <cwctype> using namespace std; ////////////////////////////////////////////////////////////////////////// C99 增加 #include <complex.h>   //复数处理 #include <fenv.h>    //浮点环境 #include <inttypes.h>  //整数格式转换 #include <stdbool.h>   //布尔环境 #include <stdint.h>   //整型环境 #include <tgmath.h>   //通用类型数学宏 --------------------------------------------------------------------------------------------------------- 补充: 经常在CSDN以及其他之类的技术论坛上问关于C++ 头文件的问题。提出这些问题的往往就是那些刚学C++的新手。当初我是菜鸟的时候也问过类似的问题。 现在来看看下面两个include: #include<iostream> // 这个就是1998年标准化以后的标准头文件 #include<iostream.h> // 这个就是标准化以前的头文件 更本质上的区别就是iostream把标准C++库的组件放在一个名位std的namespace里面。而相对的iostream.h则将这些标准组件放在全局空间里,同时在标准化以后旧有的C标准库也已经经过改造了。 看看下面这两个头文件 // 标准化后经过改造的C的标准库,所有的组件都放在了std中 #include<cstdio> // 标准化以前C++中的C标准库 #include<stdio.h> // 在看看这个头文件C标准库下 基于char* 的字符处理函数库 #include<string.h> // 在标准化以后他变成了这样 #include<cstring> // 但是很多朋友还看见过这个字符串处理函数库,他包含了新的string class #include<string> 经过了标准委员会如此大规模手术后,在98年以前出品的C++编译器(BC3.0,BC5.0)上能顺利通过编译的源文件,在支持新标准的编译器上可能无法顺利通过编译也就是很正常的事了。 [起因] 在回过头来看看标准程序库,这个程序库涵盖范围相当广大,提过了许许多多好用的功能。正是因为这样标准程序库中class的名称和函数名与第三方提供的程序库中的class名或是函数名发生名字冲突的可能性大大增大。为了避免这个问题的发生,标准委员会决定将标准程序库中每一样东西都放在namespace std中。但是这么做同时有引来了一个新的问题。很多C++程序代码依赖那些已经存在很多年的C++ “准”标准程序库(C++迟迟未标准化才导致这些情况的发生),例如iosteam.h,complex.h等等。 为了解决这个新出现的问题,标准化委员会决定设计一些新的头文件名,给那些穿上std外衣的组件所使用。把C++头文件的.h去掉,于是就有前面出现的iostream,同样C的头文件也做了相同的处理,同时在前面加上了一个字母c,以表示是C的头文件(感觉上有中种族歧视的感觉)。同时标准化委员会声明就有的C++头文件将不再列于被支持的名单之中了,而旧有的C头文件为了满足“对C的兼容性”这个古老契约,仍然将继续存活下去。 但是,那些编译器厂商不可能去推翻他们客户的旧有编译器(也跟本不会去这么做),所以那些旧有的C++头文件仍然苟延残喘的活了下来,并不断的扰乱那些C++新兵的心智。 下面就是现在大多数C++开发工具表示头文件的组织状态: 1. 旧的C++头文件 比如iostream.h,他们虽然被标准化委员会所抛弃,但由于各大厂商为了各自的商业利益仍然将继续存活下去,这些头文件的内容将不处于namespace std中。 2. 新的C++头文件如iostream虽然提供了和旧有头文件相同的功能,但他的内容都并入了namespace std中,从而有效避免了名字污染的问题。 3. 标准C的头文件如stdio.h继续获得支持,这类文件的内容并未放在std中。 4. C函数库的技能也有对应的新式C++版本,起名称类似cstdio,这类头文件的内容也有幸穿上了std的外衣。 其实标准化以后的标准程序库的改动并不只有这些而已,很多的标准化组件都被“tamplate化”。其中就有元老级人物iostream。标准程序库的问题并不是用一篇,两篇文章就可以说清楚的。如果你像进一步的了解C++的标准程序库的话,你可以看看侯先生的《C++标准程序库》。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值