数据结构基础-栈和队列

本文详细介绍了栈和队列的概念,包括它们的顺序存储和链式存储实现,以及在括号匹配、表达式求值、递归调用和层次遍历等场景的应用。通过C++代码实例演示了栈(如递归斐波那契数列)和队列(如层次遍历二叉树)的典型操作。
摘要由CSDN通过智能技术生成

栈和队列

  • 栈和队列概念
  • 栈和队列顺序存储
  • 栈和队列链式存储
  • 栈和队列应用

顺序存储

//顺序栈
#include<iostream>
#include<stdlib.h>
#define maxsize 50
#define elementtype int
using namespace std;

typedef struct{
	elementtype data[maxsize];
	int top;	
}sqStack;

void InitStack(sqStack &s){
	s.top = -1;
}
bool stackEmpty(sqStack s){
	if(s.top == -1)
	 return true;
	else 
	 return false;
}
bool Push(sqStack &s,int x){
	/*It's wrong:
	s.top should -1 to recover former number
	s.top ++;
	if(s.top >= maxsize) return false;
	s.data[s.top] = x;
	return true;
	*/
	if(s.top >= maxsize-1) return false;
	s.data[++s.top] = x;
	return true;
}
bool Pop(sqStack &s,int &x){
	if(s.top == -1) return false;
	x = s.data[s.top];
	s.top --;
	return true;
}
bool getTop(sqStack s,int &x){
	if(s.top == -1) return false;
	x = s.data[s.top];
	return true;
}
void print(sqStack s){
	while(s.top!=-1){
		cout<<s.data[s.top]<<" ";
		s.top --;
	}
}
//基本操作 O(1)
//遍历 O(n) 
int main(){
	sqStack s;
	InitStack(s);
	cout<<"是否为空 (1/0):"<<stackEmpty(s)<<"\n";
	Push(s,1);
	Push(s,2);
	Push(s,3);
	int x;
	cout<<"获取栈顶元素(1/0):"<< getTop(s,x)<<" ";
	cout<<"栈顶元素= "<<x<<"\n";
	cout<<"遍历栈:";
	print(s);
	cout<<endl;
	cout<<"弹出栈顶元素(1/0):"<< Pop(s,x)<<" ";
	cout<<"栈顶元素= "<<x<<"\n";
	cout<<"遍历栈:";
	print(s);
}
  • 队列
//顺序队列
#include<iostream>
#include<stdlib.h>
using namespace std;

#define maxsize 50
#define elemtype int

typedef struct{
	elemtype data[maxsize];
	int front ,rear;
}sqQueue;

void initQueue(sqQueue &q){
	q.front=0;
	q.rear=0;
} 
bool isEmpty(sqQueue q){
	if(q.front==q.rear==0)
		return true;
	else return false;
}
bool enter(sqQueue &q,int x){
	if(q.rear >= maxsize-1) return false;
	q.data[q.rear++] =x;
	return true;
}
bool out(sqQueue &q,int &x){
	if(q.front == q.rear) return false;
	x = q.data[q.front++];
	return true;
}
bool getHead(sqQueue q,int &x){
	if(q.front == q.rear) return false;
	x = q.data[q.front];
	return true;
}
void print(sqQueue q){
	for(int i = q.front;i<q.rear;i++){
		cout<<q.data[i]<<" ";
	}
}

int main(){
	sqQueue q;
	initQueue(q);
	cout<<"是否为空 (1/0):"<<isEmpty(q)<<"\n";
	enter(q,1);
	enter(q,2);
	enter(q,3);
	int x;
	cout<<"获取队首元素(1/0):"<< getHead(q,x)<<" ";
	cout<<"队首元素= "<<x<<"\n";
	cout<<"遍历队:";
	print(q);
	cout<<endl;
	cout<<"弹出队首元素(1/0):"<< out(q,x)<<" ";
	cout<<"队首元素= "<<x<<"\n";
	cout<<"遍历队:";
	print(q);
}
  • 循环队列
//循环队列
#include<iostream>
#include<stdlib.h>
using namespace std;

#define maxsize 50
#define elemtype int

typedef struct{
	elemtype data[maxsize];
	int front ,rear;
}sqQueue;

void initQueue(sqQueue &q){
	q.front=0;
	q.rear=0;
} 
bool isEmpty(sqQueue q){
	if(q.front==q.rear)//不再==0 
		return true;
	else return false;
}
bool enter(sqQueue &q,int x){
	if((q.rear+1)%maxsize == q.front) //不再q.rear>=maxsize-1 
	return false;
	q.data[q.rear] =x;
	q.rear = (q.rear+1)%maxsize;//不再rear++ 
	return true;
}
bool out(sqQueue &q,int &x){
	if(q.front == q.rear)
		return false;
	x = q.data[q.front];
	q.front = (q.front+1)%maxsize;//不再front++ 
	return true;
}
/*不再有常规意义的队首 
bool getHead(sqQueue q,int &x){
	if(q.front == q.rear) return false;
	x = q.data[q.front];
	return true;
}
*/ 
void print(sqQueue q){
	for(int i = q.front;i<q.rear;i++){
		cout<<q.data[i]<<" ";
	}
}
//缺陷:print函数未修改,当maxsize变小(front和rear围成环时),存在问题 
int main(){
	sqQueue q;
	initQueue(q);
	cout<<"是否为空 (1/0):"<<isEmpty(q)<<"\n";
	enter(q,1);
	enter(q,2);
	enter(q,3);
	int x;
	//cout<<"获取队首元素(1/0):"<< getHead(q,x)<<" ";
	//cout<<"队首元素= "<<x<<"\n";
	//cout<<"遍历队:";
	//print(q);
	//cout<<endl;
	cout<<"弹出队首元素(1/0):"<< out(q,x)<<" ";
	cout<<"队首元素= "<<x<<"\n";
	cout<<"遍历队:";
	print(q);
} 

链式存储

//链栈
#include<iostream>
#include<stdlib.h> 
using namespace std;

#define elemtype int
typedef struct linkNode{
	elemtype data;
	struct linkNode *next;
}*linkStack;
//带头结点的
void initStack(linkStack &s){
	s = (linkStack)malloc(sizeof(linkNode));
	s->next = NULL;
}
bool isEmpty(linkStack &s){
	if(s->next == NULL) return true;
	else return false;
}
bool Push(linkStack &s,int x){
	linkStack n;
	n = (linkStack)malloc(sizeof(linkNode));
	n->data = x;
	n->next = s->next;
	s->next = n;
	return true;
}
bool Pop(linkStack &s,int &x){
	if(s->next == NULL) return false;
	x = s->next->data;
	s->next = s->next->next;
}
bool getTop(linkStack &s,int &x){
	if(s->next == NULL) return false;
	x = s->next->data;
	return true;
}
void print(linkStack s){
	while(s->next!=NULL){
		cout<<s->next->data<<" ";
		s = s->next;
	}
}
int main(){
	linkStack s;
	initStack(s);
	cout<<"是否为空 (1/0):"<<isEmpty(s)<<"\n";
	Push(s,1);
	Push(s,2);
	Push(s,3);
	int x;
	cout<<"获取栈顶元素(1/0):"<< getTop(s,x)<<" ";
	cout<<"栈顶元素= "<<x<<"\n";
	cout<<"遍历栈:";
	print(s);
	cout<<endl;
	cout<<"弹出栈顶元素(1/0):"<< Pop(s,x)<<" ";
	cout<<"栈顶元素= "<<x<<"\n";
	cout<<"遍历栈:";
	print(s);
}
  • 队列
//链队列
#include<iostream>
#include<stdlib.h>
using namespace std;

#define elemtype int

typedef struct linkNode{
	elemtype data;
	struct linkNode *next;
}linkNode;

typedef struct{
	linkNode *front,*rear;
}linkQueue;

void initQueue(linkQueue &q){
	q.front = q.rear = (linkNode*)malloc(sizeof(linkNode));
	q.front->next = NULL;
} 
bool isEmpty(linkQueue q){
	if(q.front==q.rear)
		return true;
	else return false;
}
bool enter(linkQueue &q,int x){
	linkNode *s = (linkNode*)malloc(sizeof(linkNode));
	s->data =x; s->next = NULL;
	q.rear->next = s;
	q.rear = s;
	return true;
}
bool out(linkQueue &q,int &x){
	if(q.front == q.rear) return false;
	linkNode *s = q.front->next;//head node s 
	x = s->data;
	q.front->next = s->next;//出队,指向下一个元素 
	if(q.rear == s){//当只有一个元素 
		q.rear = q.front;
	}
	free(s);
	return true;
}
//bool getHead(linkQueue q,int &x){
//	if(q.front == q.rear) return false;
//	x = q.data[q.front];
//	return true;
//}
void print(linkQueue q){
	while(q.front != q.rear){
		cout<<q.front->next->data<<" ";
		q.front = q.front->next;
	} 
}

int main(){
	linkQueue q;
	initQueue(q);
	cout<<"是否为空 (1/0):"<<isEmpty(q)<<"\n";
	enter(q,1);
	enter(q,2);
	enter(q,3);
	int x;
//	cout<<"获取队首元素(1/0):"<< getHead(q,x)<<" ";
//	cout<<"队首元素= "<<x<<"\n";
//	cout<<"遍历队:";
//	print(q);
//	cout<<endl;
	cout<<"弹出队首元素(1/0):"<< out(q,x)<<" ";
	cout<<"队首元素= "<<x<<"\n";
	cout<<"遍历队:";
	print(q);
}

应用

1. 栈的括号匹配
#include<iostream>
using namespace std;
//栈的括号匹配
#include<stdlib.h>
#define maxsize 50
#define elementtype char
using namespace std;

typedef struct{
	elementtype data[maxsize];
	int top;	
}sqStack;

void InitStack(sqStack &s){
	s.top = -1;
}
bool isEmpty(sqStack s){
	if(s.top == -1)
	 return true;
	else 
	 return false;
}
bool Push(sqStack &s,elementtype x){
	if(s.top >= maxsize-1) return false;
	s.data[++s.top] = x;
	return true;
}
bool Pop(sqStack &s,elementtype &x){
	if(s.top == -1) return false;
	x = s.data[s.top];
	s.top --;
	return true;
}
bool getTop(sqStack s,elementtype &x){
	if(s.top == -1) return false;
	x = s.data[s.top];
	return true;
}
void print(sqStack s){
	while(s.top!=-1){
		cout<<s.data[s.top]<<" ";
		s.top --;
	}
}
bool lr(char s,char s1){
	if(s=='[' && s1==']') return true;
	else if(s=='(' && s1==')') return true;
	else if(s=='{' && s1=='}') return true;
	else return false;
}
int main(){
	sqStack s;
	InitStack(s);
	char ch;
	int len; 
	cout<<"请输入{([或])}组成的字符串长度:"<<" "; 
	cin>>len; 
	while(len--){
		cin>>ch;
		if(ch =='['||ch =='('||ch=='{'){
			Push(s,ch);
		}
		else{
			char tmp;
			Pop(s,tmp);
			if(!lr(tmp,ch)){
				cout<<ch<<" "<<tmp;
				cout<<"wrong\n";
				break;
			}		
		}	
	}
	if(isEmpty(s)){
		cout<<"succese\n";
	}else{
		cout<<"wrong\n";
	}
}
2. 栈的表达式求值
//栈的表达式求值
#include<iostream>
#include<stdlib.h>
using namespace std;

#define maxsize 50
#define elementtype int

typedef struct{
	elementtype data[maxsize];
	int top;	
}sqStack;

void InitStack(sqStack &s){
	s.top = -1;
}
bool isEmpty(sqStack s){
	if(s.top == -1)
	 return true;
	else 
	 return false;
}
bool Push(sqStack &s,elementtype x){
	if(s.top >= maxsize-1) return false;
	s.data[++s.top] = x;
	return true;
}
bool Pop(sqStack &s,elementtype &x){
	if(s.top == -1) return false;
	x = s.data[s.top];
	s.top --;
	return true;
}
bool getTop(sqStack s,elementtype &x){
	if(s.top == -1) return false;
	x = s.data[s.top];
	return true;
}
void print(sqStack s){
	while(s.top!=-1){
		cout<<s.data[s.top]<<" ";
		s.top --;
	}
}
//简单:后缀表达式求值
void sample(){
	char ch[11] = {'1','9','3','2','-','*','+','1','9','/','-'};
	//1+9*(3-2)-1/9
	sqStack s;
	InitStack(s);
	int i = 0;
	while(i<11){
		if(ch[i]<='9' && ch[i]>='0'){
			int a = (int)(ch[i]-'0');
			Push(s,a);
		}else if(ch[i] == '+'){
			int a,b;
			Pop(s,a);
			Pop(s,b);
			Push(s,a+b);
		}else if(ch[i] == '-'){
			int a,b;
			Pop(s,a);
			Pop(s,b);
			Push(s,b-a);
		}else if(ch[i] =='*'){
			int a,b;
			Pop(s,a);
			Pop(s,b);
			Push(s,a*b);
		}else if(ch[i] =='/'){
			int a,b;
			Pop(s,a);
			Pop(s,b);
			Push(s,b/a);
		}else{
			break;
		}
		i++;
	}
	int x;
	getTop(s,x);
	cout<<x<<endl;
} 
int main(){
	sample();
}
3. 栈的递归
//栈的递归调用
//斐波拉契数列
#include<iostream>
using namespace std;
int fib(int n){
	if(n == 0) return 0;
	else if(n == 1) return 1;//边界
	else return fib(n-1)+fib(n-2); 
} 
//when n is bigger,the stack well be not enough
int fib_2(int n){
	int f0=0,f1=1;
	int ans = 0;
	if(n == 0) return f0;
	else if(n == 1) return f1;//边界
	
	for(int i = 2;i <= n;i++){
		ans = f0 + f1;
		f0=f1;
		f1=ans;
	}
	return ans;
} 
int main(){
	int n;
	cin>>n;
	cout<<fib(n)<<" "<<fib_2(n);
	//stack: main()->fib(2)->fib(1) and fib(0)
	//return main()<-fib(2)<-fib(1) + fib(0)  
}
4. 队列的层次遍历
#include<iostream>
#include<stdlib.h>
#include<queue> 
using namespace std;

typedef struct node{
	int data;
	struct node* left;
	struct node* right;
}Node;

typedef struct{
	Node* root;
}tree;

void insert(tree* t,int value){
	Node* n =(Node*)malloc(sizeof(Node));
	n->data = value;
	n->left = NULL;
	n->right = NULL;
	if(t->root == NULL){
		t->root = n;
	}else{
		Node* temp = t->root;
		while(temp!=NULL){
			if(value <temp->data){
				if(temp->left == NULL){
					temp->left = n;
					return;
				}else{
					temp = temp->left;
				}
			}else{
				if(temp->right == NULL){
					temp->right = n;
					return ;
				}else{
					temp = temp->right;
				}
			}
		}
	}
	return;
}
void inorder(Node* n)//中序遍历
{
	if(n!=NULL){
		inorder(n->left);
		cout<<n->data<<" ";
		inorder(n->right);
	}
}
//采用了STL库集成的queue,没有使用自定义的queue 
void chengci(Node* n){//层次遍历 
	queue<Node*> q;
	q.push(n);
	while(!q.empty()){
		Node* p = q.front();
		if(p->left!=NULL){
			q.push(p->left);
		}
		if(p->right!=NULL){
			q.push(p->right);
		}
		q.pop();
		cout<<p->data<<" ";
	}
}
void make(){
	tree t;
	t.root =NULL;
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		int temp;
		cin>>temp;
		insert(&t,temp);
	}
	cout<<"中序遍历:";
	inorder(t.root);cout<<endl;
	cout<<"队列的层次遍历:"; 
	chengci(t.root);cout<<endl;
}
int main(){
	make();
}

其他

内容链接
绪论上一篇博客
线性表上一篇博客:线性表
栈和队列正在翻阅此文章
树和二叉树下一篇博客:树和二叉树
下一篇博客:图
查找下一篇博客:查找
排序下一篇博客:排序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值