栈
本质是线性表,但只有一端可以进行元素增删,先进后出(FILO),增加了约束(如果用数组实现可能出现人工错误)。
实现方式:顺序表、链表、stl(stack)
顺序表实现:
1
#include<iostream>
using namespace std;
struct Stack{
int *datas;//指针动态分配内存
int bufferlen;
int top;
};
int InitStack(Stack &S,int n){
S.datas=new int[n];
S.bufferlen=0;
S.top=0;
return 0;
}
int DestroyStack(Stack &S){
delete[]S.datas;
S.datas=NULL;
S.bufferlen=0;
S.top=0;
return 0;
}
int Empty(Stack &S){
return S.top==0;
}
int Top(Stack &S){//这种方式不是很好,因为栈可能空
return S.datas[S.top-1];
}
int Push(Stack &S,int data){
if(S.top>=S.bufferlen)return 1;//栈满返回1
S.datas[S.top]=data;
S.top++;
return 0;
}
//出栈
int Pop(Stack &S){
if(Empty(S))return 1;
S.top--;
return 0;
}
int main(){
Stack S;
InitStack(S, 100);
int op;
while ((op = ShowMenu()) != 0)
{
switch (op)
{
case 1:
{
// 车厢进栈
int aNo;
cout << "请输入进栈车厢号:";
cin >> aNo;
Push(S, aNo);
cout << aNo << "号车厢进栈完毕。" << endl;
break;
}
case 2:
{
// 车厢出栈
if (Empty(S))
{
cout << "货栈里是空的,没有车厢可以出栈了。" << endl;
}
else
{
int aNo = Top(S);
Pop(S);
cout << aNo << "号车厢出栈。" << endl;
}
break;
}
}
}
DestroyStack(S);
return 0;
}
2
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
#define MAXSIZE 100
struct Stack{
int data[MAXSIZE];//规定长度
int len;//栈顶标识
};
void InitStack(Stack& S){
S.len=0;
}
bool IsEmpty(const Stack& S){
return (S.len==0);
}
int push(Stack& S,int e){
if(S.len>=MAXSIZE)return -1;
S.data[S.len++]=e;
return 0;
}
int top(Stack& S,int& e){
if(IsEmpty(S))return -1;
e=S.data[S.len-1];
return 0;
}
int pop(Stack& S,int& e){
if(IsEmpty(S))return -1;
top(S,e);
S.len-=1;
return 0;
}
void Print(const Stack& S){
for(int i=0;i<S.len;i++){
cout<<S.data[i]<<" ";
}
cout<<endl;
}
int main(){
Stack S;
InitStack(S);
int out[5]={3,1,2,4,5};
int index = 1;
string op;
for(int i=0;i<5;){
if(IsEmpty(S)){
for(int j=index;j<=out[i];j++){
push(S,j);
//cout<<"P";
op+='P';
}
index=out[i]+1;
}else{
int e;
top(S,e);
if(e==out[i]){
pop(S,e);
//cout<<"Q";
op+='Q';
i++;
}else if(out[i]>e){
for(int j=index;j<=out[i];j++){
push(S,j);
//cout<<"P";
op+='P';
}
index=out[i]+1;
}else if(out[i]<e){
cout<<"failed"<<endl;
break;
}
}
}
return 0;
}
链表实现
无需头结点
#include<iostream>
#include<cstring>
#include<string>
#include<stack>
using namespace std;
#define MAXSIZE 100
//template <typename T>
struct StackNode{
int data;
StackNode* next;
};
//typedef StackNode* Stack;
void InitStack(Stack& S){
S=nullptr;
}
bool IsEmpty(const Stack& S){
return (S==nullptr);
}
int push(Stack& S,int e){
StackNode* node=new StackNode();//错误会自动退出
node->data=e;
node->next=S;
S=node;
return 0;
}
int top(Stack& S,int& e){
if(IsEmpty(S))return -1;
e=S->data;
return 0;
}
int pop(Stack& S,int& e){
if(IsEmpty(S))return -1;
top(S,e);
StackNode* p=S;
S=S->next;
delete p;
return 0;
}
void Print(const Stack& S){
StackNode* p=S;
while(p!=nullptr){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main(){
stack<int> s;
Stack S;
InitStack(S);
int out[5]={3,2,4,5,1};
int index = 1;
string op;
for(int i=0;i<5;){
if(IsEmpty(S)){
for(int j=index;j<=out[i];j++){
push(S,j);
//cout<<"P";
op+='P';
}
index=out[i]+1;
}else{
int e;
top(S,e);
if(e==out[i]){
pop(S,e);
//cout<<"Q";
op+='Q';
i++;
}else if(out[i]>e){
for(int j=index;j<=out[i];j++){
push(S,j);
//cout<<"P";
op+='P';
}
index=out[i]+1;
}else if(out[i]<e){
cout<<"failed"<<endl;
break;
}
}
}
return 0;
}
#stl实现
#include <iostream>
#include <stack>
using namespace std;
int main()
{
stack<int> s;
for (int i = 0; i < 10; i++)s.push(i);
while (!s.empty())
{
cout << s.top() << ", ";
s.pop();
}
return 0;
}
例题:括号匹配问题,进制转换问题,表达式计算问题(计算由常数和二元运算符,括号组成的四则运算表达式)±*/() #开始 结束 用M二维数组记录运算符优先级
栈与递归
队列
唯一入口唯一出口,先进先出FIFO
顺序结构实现:循环队列(以免浪费空间),比较麻烦要处理下标
int n=5;
int head=0;
int tail=-1;
a入队tail++;
b入队 tail++;
a出队 head++;
index=(index+1)%bufferlen
a b c d e队满如何判断?
应放在0的位置,head=0,(tail+1)%5==head,相等因此队满
队空:tail==head
链式结构实现
优先队列:队列中的元素按照关键字有序排序,出队相同,入队操作=有序表的插入操作
#include <iostream>
using namespace std;
// 操作菜单
int ShowMenu(){
cout << "1. 货车入库" << endl;
cout << "2. 货车出库" << endl;
cout << "0. 退出" << endl;
cout << "请选择操作:";
int op;
cin >> op;
return op;
}
struct QueueNode{ //链式队列
int data;
QueueNode *next;
};
struct Queue{ //头结点尾结点
QueueNode *head, *tail;
};
// 初始化
int InitQueue(Queue &Q) {
Q.head = Q.tail = NULL;
return 0;
}
//判断队空,空返回1
bool Empty(Queue Q){
return Q.head == NULL;
}
int DeQueue(Queue &Q){
if (Empty(Q)) return 1;
// 暂存队首结点
QueueNode *p = Q.head;
// 摘除队首结点
Q.head = Q.head->next;
if (Q.head == NULL) Q.tail = NULL;
// 删除摘下的队首结点
delete p;
return 0;
}
// 撤销
int DestroyQueue(Queue &Q){
while (!Empty(Q))DeQueue(Q);
return 0;
}
// 读取队首元素
int Top(Queue Q){
return Q.head->data;
}
// 入队
int EnQueue(Queue &Q, int data){
// 创建新结点
QueueNode *p = new QueueNode;
p->data = data;
p->next = NULL;
// 入队
if (Q.tail == NULL){
Q.head = Q.tail = p;
}
else{
Q.tail->next = p;
Q.tail = p;
}
return 0;
}
int main()
{
Queue Q;
InitQueue(Q, 100);
int op;
while ((op = ShowMenu()) != 0)
{
switch (op)
{
case 1:
{
// 货车入库
int aNo;
cout << "请输入入库货车号:";
cin >> aNo;
if (EnQueue(S, aNo) != 0)cout << "入库失败!" << endl;
else cout << aNo << "号货车入库完毕。" << endl;
break;
}
case 2:
{
// 货车出库
if (Empty(Q))
cout << "车库里是空的,没有货车可以出库了。" << endl;
else{
int aNo = Top(Q);
DeQueue(Q);
cout << aNo << "号货车出库。" << endl;
}
break;
}
}
}
DestroyQueue(Q);
return 0;
}
stl实现
#include <iostream>
#include <queue>
using namespace std;
int main(){
queue<int> s;
for (int i = 0; i < 10; i++)s.push(i);
while (!s.empty()){
cout << s.front() << ", ";
s.pop();
}
return 0;
}