**

C++容器简介1—stack

**
引用链接 参考文献:C++ Primer 第五版

一、简介

stack是一种容器适配器(STL的容器分为顺序容器和关联容器,容器适配器),被设计来用于操作先进后出(FILO)结构的情景,在这种情况下, 元素的插入和删除都只能在容器的尾部进行。
   stack通过容器适配器来实现,是一种将特定的容器类作为其最底层的容器的类,它提供了一些特定的成员函数来访问自己的元素,元素只能在这个特定容器的后面,也就是栈的顶部,进行出栈和入栈操作。
   最底层的容器可以是任意一种标准的容器模板类,或者是一些有明确目的的容器类,他们应该支持以下操作:
	              empty(判断是否为空)
	              size (返回栈的元素个数)
	              back (返回栈顶元素)
	              push (入栈)
	              pop(出栈)
    标准的容器类,比如vector,deque,list,满足以上需求。如果没有明确指定需要使用的容器,默认情况下将会使用deque。

二、stack相关函数用法

#include <iostream>
using namespace std;
#include <stack>                              
void main01()               //栈模型          
{
	stack<int> s;
	for (int i = 0; i < 10; i++)
	{
		s.push(i + 1);      //入栈
	}
	cout << "栈的大小: " << s.size() << endl;
	while (!s.empty())      //出栈
	{
		int tmp = s.top();  //获取栈顶元素
		cout << tmp<<" ";
		s.pop();			//弹出栈顶元素
	}
	cout << endl;
}
class Teacher
{
public:
	int age;
	char name[32];
public:
	void printT()
	{
		cout << "age: " << age << endl;
	}
};
void main02()				 //结构体
{
	Teacher t1, t2, t3;
	t1.age = 31;
	t2.age = 32; 
	t3.age = 33;
	stack<Teacher> s;
	s.push(t1);
	s.push(t2);
	s.push(t3);
	while (!s.empty())
	{
		Teacher tmp = s.top();
		tmp.printT();
		s.pop();
	}
}
void main03()            //结构体指针
{
	Teacher t1, t2, t3;
	t1.age = 31;
	t2.age = 32;
	t3.age = 33;
	stack<Teacher*> s;
	s.push(&t1);
	s.push(&t2);
	s.push(&t3);
	while (!s.empty())
	{
		Teacher *p = s.top();
		p->printT();
		s.pop();
	}
}
void main()
{
	main01();
	main02();
	main03();
	cout << endl;
	cout << "Hello" << endl;
	system("pause");
	return;
}

1、empty()

返回当前栈是否为空(当它的大小是0的时候),empty()函数并不能清空栈,只是一个返回bool型的const函数。

stack<int>s;
s.push(1);
s.push(2);
cout << s.empty() << endl;   //输出0

2、size()

返回容器中元素的个数,时间复杂度O(1),返回值类型是size_type,也就是unsigned int。size()函数不能改变栈的大小。
例如上面的代码段应该输出 2

3、top()

返回栈顶元素的引用。
由于栈是一种先进后出的结构,所以最顶部的元素就是最后插入栈的元素。
(C++11中会自动根据元素类型返回reference或者是const_reference,对一个空的栈调用top函数,会异常终止,所以应该使用empty()函数提前检查)
stack<int>s;
    s.push(1);
    s.push(2);
    cout << s.top() << endl;    //输出2
    s.top() += 3;               //引用可以作为左值
    cout << s.top() << endl;    //输出5

4、push() 和 emplace() (C++11)

push()函数和emplace()都是在栈这个容器的顶部插入一个新的元素。
push(),实际上是调用的底层容器的push_back()函数,新元素的值是push函数参数的一个拷贝。
emplace(),实际上是调用的底层容器的emplace_back()函数,新元素的值是在容器内部就地构造的,不需要移动或者拷贝。
stack的emplace也可以用在普通的基本类型上。
struct Node
{
    Node(int x)
    x(x){}
    int x;
};
int main()
{
    stack<Node>s1;
    s1.emplace(1);
    s1.push(Node(2));
    stack<int>s2;
    s2.emplace(1);   //OK
    return 0;
}

5、pop()

删除最顶部的元素,使栈的大小减小。
这个被删除的元素,是刚刚插入栈的元素,这个元素和top函数的返回值是一致的。这个函数会调用对象的析构函数(如果有的话),pop()实际上是用过底层容器的pop_back()函数实现的。
对一个空栈进行pop(),会导致程序异常终止,应该使用empty提前检查

stack<int>s;
s.push(1);
s.push(2);
s.push(3);
cout << s.top() << endl;   //3
s.pop();
cout << s.top() << endl;   //2

栈没有clear或者erase函数,如果想要清空一个栈,需要循环的调用出栈函数。

stack<int>s;
//s.erase(); //error
//s.clear(); //error
s.push(1);
s.push(2);
s.push(3);
cout << s.size() << endl;   //3
while(!s.empty())
    s.pop();
cout << s.size() << endl;    //0

6、swap()

交换两个栈的内容(所有元素),这个函数通过非成员函数swap()来交换底层容器,时间复杂度O(1)

// stack::swap
#include <iostream>  
using namespace std;
#include <stack> 
int main ()
{
  std::stack<int> foo,bar;
  foo.push (10); foo.push(20); foo.push(30);
  bar.push (111); bar.push(222);
  foo.swap(bar);
  std::cout << "size of foo: " << foo.size() << '\n';
  std::cout << "size of bar: " << bar.size() << '\n';
  return 0;
}

7、运算符重载

比较:先大小,后元素
(1)  == 
     template <class T, class Container>
     bool operator== (const stack<T,Container>& lhs, const stack<T,Container>& rhs);
(2)  重载 !=  
	 template <class T, class Container>
	 bool operator!= (const stack<T,Container>& lhs, const stack<T,Container>& rhs);
(3)  重载 <
	 template <class T, class Container>
     bool operator<  (const stack<T,Container>& lhs, const stack<T,Container>& rhs);
(4)   重载 <=   
	 template <class T, class Container>
     bool operator<= (const stack<T,Container>& lhs, const stack<T,Container>& rhs);
(5)  重载 >   
	 template <class T, class Container>
	 bool operator>  (const stack<T,Container>& lhs, const stack<T,Container>& rhs);
(6)  重载 >=   
     template <class T, class Container>
	 bool operator>= (const stack<T,Container>& lhs, const stack<T,Container>& rhs);

例子
 	 stack<int>l1;
     l1.emplace(1);
     l1.emplace(2);
     l1.emplace(3);
     stack<int>l2;
     l2.emplace(1);
     l2.emplace(2);
     cout << boolalpha << (l1 > l2) << endl;   //T
     cout << boolalpha << (l1 == l2) << endl;   //F
     cout << boolalpha << (l1 != l2) << endl;   //T