STL提供三种特殊的数据结构:栈,队列与优先队列.接下来分三篇一一详述
栈
1.定义栈:stack<Type> s;
2.栈规则:LIFO(last in first out)后进先出,限定只能在栈顶进行插入和删除操作
3.栈操作:PUSH压栈,POP弹栈(从栈顶把元素弹出),TOP取栈顶元素(不是删除),SIZE栈元素个数,EMPTY判空
用几行代码测试以下这几个基本操作:
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
int main()
{
stack<int> s;
int num;
while(cin>>num){
s.push(num);
}
while(!s.empty()){
cout<<s.top()<<",";
s.pop();
}
return 0;
}
4.栈分类:
(1)基于数组的栈——以数组为底层数据结构时,通常以数组头为栈底,数组头到数组尾为栈顶的生长方向.详情参见顺序表的基本操作
(2)基于单链表的栈——以链表为底层的数据结构时,以链表头为栈顶,便于节点的插入与删除,压栈产生的新节点将一直出现在链表的头部
5.示例
a.基于数组的栈也就是文章顺序表的基本操作中的基本操作代码
b.基于单链表的栈
#include <stack>
#include <iostream>
using namespace std;
template<class T>//声明一个模板,虚拟类型名为T
class Stack//类模板名为Stack
{
private:
struct Node
{
T data;
Node *next;
};
Node *head;
Node *p;
int length;
public:
Stack()
{
head = NULL;
length = 0;
}
void push(T n)//入栈
{
Node *q = new Node;
q->data = n;
if (head == NULL)
{
q->next = head;
head = q;
p = q;
}
else
{
q->next = p;
p = q;
}
length++;
}
T pop()//出栈并且将出栈的元素返回
{
if (length <= 0)
{
abort();
}
Node *q;
int data;
q = p;
data = p->data;
p = p->next;
delete(q);
length--;
return data;
}
int size()//返回元素个数
{
return length;
}
T top()//返回栈顶元素
{
return p->data;
}
bool isEmpty()//判断栈是不是空的
{
if (length == 0)
{
return true;
}
else
{
return false;
}
}
void clear()//清空栈中的所有元素
{
while (length > 0)
{
pop();
}
}
};
int main()
{
Stack<int> s; //用类模板定义对象时:类模板名<实际类型名> 对象名(实参表列);
s.push(1);
s.push(2);
s.push(3);
while (!s.isEmpty())
{
cout << s.pop() << endl;
}
return 0;
}
5.小练习
(1)使用两个栈,一个栈用来保存当前的元素,记做:stackDat;,一个栈用来保存压入操作每一步的最小元素,记做:stackMin。
(2)入栈:当stackData栈中压入一个数据时,判断satckMin中是否为空。若为空,将该元素压入stackMin栈中。若不空,判断两者之间的大小,当前者小于或等于后者时,将前者中的数据压入后者中;当前者大于后者时,不进行任何操作。
(3)出栈:保证stackMin中栈顶的元素是sattckData中最小的。
法一
#include<iostream>
#include <stack>
#include <cassert>
using namespace std;
//方法一: 一个辅助栈,如果这个栈为空,直接将元素入这个栈,如果辅助栈中有元素,将压入的元素和辅助栈顶元素比较,
//压入两者中较小的那个元素使得辅助栈总是维持栈顶元素为最小值。
class Stack
{
public:
void Push(int data)
{
stackData.push(data);
if (stackMin.empty())
{
stackMin.push(data);
}
else
{
int tmp = stackMin.top();
int min = data > tmp ? tmp : data;
stackMin.push(min);
}
}
void Pop()
{
assert(!stackData.empty() && !stackMin.empty());
stackData.pop();
stackMin.pop();
}
int GetMin()
{
assert(!stackMin.empty());
return stackMin.top();
}
private:
stack<int> stackData;
stack<int> stackMin;
};
int main()
{
Stack s;
//s.Push(5);
s.Push(36);
s.Push(15);
s.Push(95);
s.Push(50);
s.Push(53);
cout << s.GetMin() << endl;
system("pause");
return 0;
}
法二
#include<iostream>
#include <stack>
#include <cassert>
using namespace std;
//方法二: 一个辅助栈,如果这个栈为空,直接将元素入这个栈,如果辅助栈中有元素,将压入的元素和辅助栈顶元素比较,
//如果压入的元素小于等于辅助栈顶元素,者将这个元素入辅助栈,否则无操作,出栈的时候判断要出栈的元素是否等于辅助
//栈顶元素,如果是,也将辅助栈顶元素出栈。否则无操作。
class Stack
{
public:
void Push(int data)
{
stackData.push(data);
if (stackMin.empty())
{
stackMin.push(data);
}
else
{
if (data <= stackMin.top())
{
stackMin.push(data);
}
}
}
void Pop()
{
assert(!stackData.empty() && !stackMin.empty());
if (stackData.top() == stackMin.top())
{
stackMin.pop();
}
stackData.pop();
}
int GetMin()
{
assert(!stackMin.empty());
return stackMin.top();
}
private:
stack<int> stackData;
stack<int> stackMin;
};
int main()
{
Stack s;
//s.Push(5);
s.Push(36);
s.Push(15);
s.Push(95);
s.Push(50);
s.Push(53);
cout << s.GetMin() << endl;
system("pause");
return 0;
}//15