【数据结构】栈和队列

前言

栈和队列是两种重要的线性结构,从数据结构上来看,它们也是线性表。是操作受限的线性表。但从数据类型上来看,则大不相同。

unreal

栈(Stack)

定义

书本定义:

万兆

栈是限定仅在表尾进行插入或删除操作的线性表。表尾称为栈顶,表头称为栈底。不含元素的空表称为空栈。

技术学习

《大话数据结构》的定义:
在这里插入图片描述
在这里插入图片描述

进程间通信

栈的表示和实现

两种存储表示方法:栈的顺序存储表示—-顺序栈 栈的链式表示—–链栈
我们以顺序栈为例子进行栈的表示和实现

社交

栈的顺序存储表示

typedef struct{
	char *base;//栈底指针
	char *top;//栈顶指针
	int stacksize;//当前已分配的存储空间
}SqStack;

栈的初始化

#define SIZE 100;//存储空间初始分配量
int init(SqStack &s){
	s.base=(char*)malloc(SIZE*sizeof(char));
	if(!s.base)//开辟存储空间失败则停
		exit(0);
	s.stacksize=100;
	s.top=s.base;
	return 1;
}

元素进栈

void push(SqStack &s,char e){
//首先判断栈是否满,若满了,则需要申请新的存储空间
	if(s.top-s.base>=s.stacksize){
	//指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小),返回调整之后的空间的起始位置地址
		s.base=(char *)realloc(s.base,(s.stacksize+10)*sizeof(char));
		s.top=s.base+s.stacksize;
		s.stacksize+=10;
}
	*s.top++=e;//将值赋给s.top指向的位置,s.top++ 
}

输出出栈序列

void Out(SqStack &s){
	if(s.top!=s.base)
		printf("%c ",s.top);
		s.top++;
}

释放栈

int Clear(SqStack &s){
	if(!s.base)
		return 0;
	free(s.base);//释放内存空间
	s.base=NULL;
	s.top=NULL;
	s.stacksize=0;
	return 1;
}

完整代码如下:

社交电子

//栈的基本操作
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define SIZE 100
#define CREAT 10;
typedef struct{
char *base;
char *top;
int stacksize;
}SqStack;
//初始化栈 
int initstack(SqStack &s){
s.base=(char *)malloc(SIZE*sizeof(char));
if(!s.base)
exit(0);
s.stacksize=SIZE;
s.top=s.base ;
return 1;
}
//判断栈s是否非空
void isempty(SqStack &s){
if(s.top==s.base)
printf("该栈是空的\n");
else
printf("该栈不是空的\n");
}
//依次进栈元素 a,b,c,d,e
void Push(SqStack &s,char e){
if(s.top-s.base >=s.stacksize ){
s.base=(char*)realloc(s.base,(s.stacksize+10)*sizeof(char));
s.top=s.base+s.stacksize;
s.stacksize+=10;
  }
*s.top++=e;//将值赋给s.top指向的位置,s.top++ 
}
//输出栈的长度
int StackLength(SqStack s){
return s.top-s.base ;
}
//输出从栈顶到栈底元素
void StackTraverse(SqStack &s){
while(s.base!=s.top)
printf("%c ",*--(s.top));
printf("\n");
}
//输出出栈序列
void OutStack(SqStack &s){
if(s.top!=s.base){
printf("%c ",s.top);
s.top--;
}
// printf("\n");
}

//释放栈 
int ClearStack(SqStack &s){
if(!s.base)
return 0;
free(s.base);
s.base=NULL;
s.top =NULL;
s.stacksize =0;
return 1;
}
int main()
{
	SqStack h;
	initstack(h);
	isempty(h);
	printf("依次进栈元素 a,b,c,d,e\n");
	Push(h,'a');
	Push(h,'b');
	Push(h,'c');
	Push(h,'d');
	Push(h,'e');
	isempty(h);
	printf("该栈的长度为:");
	printf("%d\n",StackLength(h));
	printf("输出从栈顶到栈底元素:");
	StackTraverse(h);
	OutStack(h);
	isempty(h);
	ClearStack(h);
	return 0;
}

结果:
在这里插入图片描述

MyBatisPlus

栈的应用举例

数制转换

十进制数N和其他d进制数的转化
一个简单算法:
N=(N div d)*d+N mod d
例如十进制的(1248)=八进制的(2504)
题目要求:对于输入的任意一个非负十进制整数,打印输出其等值的八进制数。

遗传算法

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
#define SIZE 100
#define CREAT 10;
typedef struct{
int *base;
int *top;
int stacksize;
}SqStack;
//初始化栈 
int initstack(SqStack &s){
s.base=(int *)malloc(SIZE*sizeof(int));
if(!s.base)
exit(0);
s.stacksize=SIZE;
s.top=s.base ;
return 1;
}
//进栈 
void Push(SqStack &s,int e){
if(s.top-s.base >=s.stacksize ){
s.base=(int*)realloc(s.base,(s.stacksize+10)*sizeof(int));
s.top=s.base+s.stacksize;
s.stacksize+=10;
  }
*s.top++=e;//将值赋给s.top指向的位置,s.top++ 
}
//元素出栈
int Pop(SqStack &s,int &e){
	if(s.top==s.base)
		return 0;
	s.top--;
	e=*s.top;
	return 1;
	
} 
//判断是否为空
int StackEmpty(SqStack &S){
	if(S.top==S.base)
		return 1;
	else
		return 0;
} 
//对于输入的任意非负十进制整数,打印与其等值的八进制数 
void conversion(){
	int N,e;
	SqStack S;
	initstack(S);
	scanf("%d",&N);
	while(N){
		Push(S,N%8);
		N=N/8;
	} 
	while(!StackEmpty(S)){
		Pop(S,e);
		printf("%d",e);
	}
}
int main()
{
	conversion();
	return 0;
}

结果:
在这里插入图片描述

对称加密

括号匹配的检验

行编辑程序

迷宫求解

表达式求值

栈与递归的实现

队列

定义

队列是一种先进先出(FIFO)的线性表。在队列中,允许插入的一端叫做队尾,允许删除的一端叫做队头。
《大话数据结构》的定义:
在这里插入图片描述

魔百盒固件

链队列–队列的链式表示和实现

为了操作方便,添加一个头结点,并令头指针指向头结点。

ios拍照旋转

单链队列的表示

typedef struct QNode{
	char data ;
	struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
	QueuePtr front;//队头指针
	QueuePtr rear;//队尾指针
}LinkQueue;

初始化

void init(LinkQueue &Q){
	//构造一个空队列
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front)
		exit(0);//存储分配失败
	Q.front->next=null;
}

销毁

void destory(LinkQueue &Q){
	while(Q.front){
	Q.rear=Q.front->next;
	free(Q.front);
	Q.front=Q.rear;
}
}

插入新元素

void queue(LinkQueue &Q,char e){
	QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
	if(!p) exit(0);
	p->data=e;
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p;
}

删除队头元素

void dequeue(LinkQueue &Q,char &e){
	if(Q.front==Q.rear)
		printf("队列已空,无法执行删除操作!");
	QueuePtr p=Q.front->next;
	e=p->data;
	Q.front->next=p->next;
	if(Q.rear==p)
		Q.rear=Q.front;
	free(p);
}

完整代码如下:

虚拟机

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct QNode{
	char data ;
	struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
	QueuePtr front;//队头指针
	QueuePtr rear;//队尾指针
}LinkQueue;

void init(LinkQueue &Q){
	//构造一个空队列
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front)
		exit(0);//存储分配失败
	Q.front->next=NULL;
}

void destory(LinkQueue &Q){
	while(Q.front){
	Q.rear=Q.front->next;
	free(Q.front);
	Q.front=Q.rear;
}
}

void queue(LinkQueue &Q,char e){
	QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
	if(!p) exit(0);
	p->data=e;
	p->next=NULL;
	Q.rear->next=p;
	Q.rear=p;
}

void dequeue(LinkQueue &Q,char &e){
	if(Q.front==Q.rear)
		printf("队列已空,无法执行删除操作!");
	QueuePtr p=Q.front->next;
	e=p->data;
	Q.front->next=p->next;
	if(Q.rear==p)
		Q.rear=Q.front;
	free(p);
}
int size(LinkQueue &Q){
	int size=0;
	QueuePtr exp=Q.front;
	while(exp){
		size++;
		exp=exp->next;
	}
	return size;
}
int main(){
	LinkQueue Q;
	printf("初始化顺序队列\n");
	init(Q);
	printf("向数列插入元素abcde\n");
	queue(Q,'a');
	queue(Q,'b');
	queue(Q,'c');
	queue(Q,'d');
	queue(Q,'e');
	printf("输出该队列个数\n");
	printf("%d\n",size(Q)-1);
	printf("销毁该队列\n");
	destory(Q);
	printf("输出该队列个数\n");
	printf("%d\n",size(Q));
	return 0;
} 

结果:
在这里插入图片描述

yolov7

循环队列–队列的顺序表示和实现

把队列的这种头尾相接的顺序存储结构称为循环队列。

big data

《大话数据结构》
在这里插入图片描述
由此可见,在C语言中不能使用动态分配的一维数组来实现循环队列,如果用户的应用程序中设有循环队列,则必须为它设定一个最大队列长度。

bootloader

队列的顺序存储结构(循环队列)

typedef struct{
	char *base;//初始化的动态分配存储空间
	int front;//头指针
	int rear; //尾指针
}SqQueue;

初始化

#define SIZE 100//定义该循环队列存储空间为100
int init(SqQueue &Q){
	Q.base=(Elemtype*)malloc(SIZE*sizeof(Elemtype));
	if(!Q.base)
		exit(0); 
	Q.front=0;
	Q.rear=0;
	return 1;
}

队列的长度

int Queuelength(SqQueue &Q){
	return (Q.rear-Q.front+SIZE)%SIZE;
}

插入新元素

int push(SqQueue &Q,int e){
	if((Q.rear+1)%SIZE==Q.front)
		{
			printf("该队列已满,不可插入新元素");
			return 0;
		}
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%SIZE;
	return 1;
}

出队一个元素,输出该元素

int Out(SqQueue &Q,Elemtype &e){
	if(Q.front==Q.rear)
		return 0;
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%SIZE;
	return 1;
}

输出出队序列

void print(SqQueue &Q){
	int i=Q.front;
	for(;i<Q.rear;i++)
		print("%c ",Q.base[i]);
}

释放队列

void clear(SqQueue &Q){
	if(Q.base)
		free(Q.base);
		Q.base=NULL;
		Q.front=Q.rear=0;
}

完整代码:

ai


 //顺序队列的基本操作
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define SIZE 100
typedef char Elemtype;
typedef int Status;
typedef struct{
	Elemtype *base;//初始化的动态分配存储空间
	int front;
	int rear; 
}SqQueue;

// 初始化队列q
Status initQueue(SqQueue &Q){
	Q.base=(Elemtype*)malloc(SIZE*sizeof(Elemtype));
	if(!Q.base)
		exit(0); 
	Q.front=0;
	Q.rear=0;
	return 1;
} 

//判断队列q是否非空
void isempty(SqQueue &Q)
{
	if(Q.rear==Q.front)
		printf("该队列为空\n");
	else
		printf("该队列不为空\n");
}

//依次进队列元素a,b,c
Status Push(SqQueue &Q,Elemtype e){
	if((Q.rear+1)%SIZE==Q.front)
		{
			printf("抱歉,这个队列已经满了,无法插入新的元素");
			return 0;
		 } 
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%SIZE;
	return 1;
}

//出队一个元素,输出该元素
Status OutQueue(SqQueue &Q,Elemtype &e){
	if(Q.front==Q.rear)
		return 0;
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%SIZE;
	return 1; 
}
//输出队列q的元素个数
Status Queuelength(SqQueue &Q){
	return(Q.rear-Q.front+SIZE)%SIZE;
}
//输出出队序列
void Print(SqQueue &Q)
{
	int i=Q.front;
	for(;i<Q.rear;i++)
		printf("%c ",Q.base[i]);
 } 
//释放队列
Status Clear(SqQueue &Q){
	if(Q.base)
		free(Q.base);
	Q.base=NULL;
	Q.front=Q.rear=0;
	return 1;
}
int main(){
	SqQueue q;
	Elemtype e;
	printf("初始化队列q\n");
	initQueue(q);
	
	printf("判断队列q是否非空\n");
	isempty(q);
	
	printf("依次进队列元素a,b,c\n");
	Push(q,'a');
	Push(q,'b');
	Push(q,'c');
	
	OutQueue(q,e);
	printf("出队的元素为%c\n",e);
	
	printf("输出队列q的元素个数:");
	printf("%d",Queuelength(q));
	printf("\n");
	
	printf("依次进队列元素d,e,f\n");
	Push(q,'d');
	Push(q,'e');
	Push(q,'f');
	
	printf("输出队列q的元素个数:");
	printf("%d",Queuelength(q));
	printf("\n");
	
	printf("输出出队序列:");
	Print(q);
	printf("\n"); 
	
	printf("释放队列\n");
	Clear(q);
	return 0;
}

结果:
在这里插入图片描述

苹果ios解锁大师

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注