c++数据结构:栈和队列

本质是线性表,但只有一端可以进行元素增删,先进后出(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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值