【数据结构】栈与队列

本文详细介绍了栈和队列的基本概念、数据结构以及操作方法,包括顺序栈、链栈、共享栈、顺序队、环形队和链队的实现。通过实例展示了栈的对称串判断和括号匹配,以及队列的环形队列实现和报数出列顺序。此外,还提及了双端队列的操作。这些内容深入浅出地揭示了栈和队列在算法和数据处理中的重要作用。
摘要由CSDN通过智能技术生成

栈的定义


在这里插入图片描述

顺序栈


基本算法

  • 声明顺序栈
typedef struct{
	ElemType data[MaxSize];		//存放栈中的数据元素
	int top;					//栈顶指针,即存放栈顶元素在data数组中的下标 
}SqStack;

在这里插入图片描述

  • 初始化栈
void InitStack(SqStack * & s){
	s = (SqStack * )malloc(sizeof(SqStack));	//分配一个顺序栈空间,首地址存放在s中
	s->top = -1; 
}
  • 销毁栈
void DestroyStack(SqStack * &s){
	free(s);
}
  • 判断栈是否为空
bool StackEmpty(SqStack * s){
	return(s->top == -1);
}
  • 进栈
bool Push(SqStack * &s,ElemType e){
	if(s->top == MaxSize-1)		//栈满情况,即栈上溢出 
		return false;
	s->top++;					//栈顶指针增1 
	s->data[s->top] = e;		//元素e放在栈顶指针处 
	return true;
}
  • 出栈
bool Pop(SqStack * &s,ElemType &e){
	if(s->top == -1)				//栈为空的情况,即栈下溢出 
		return false;
	e = s->data[s->top];			//取栈顶元素
	s->top--;						//栈顶指针减1 
	return true;
}
  • 取栈顶元素
bool GetTop(SqStack * s,ElemType &e){
	if(s->top == -1)	//栈为空的情况,即栈下溢出
		return false;
	e = s->data[s->top]	//取栈顶元素
	return true; 
}

应用

在这里插入图片描述

bool symmetry(ElemType str[]){		//判断str是否为对称串
	int i;ElemType e;
	SqStack * st;					//定义顺序栈指针 
	InitStack(st); 					//初始化栈
	for(i = 0;str[i]!='\0';i++){	//将str的所有元素进栈
		Push(st,str[i]);
	} 
	for(i = 0;str[i]!='\0';i++){	//处理str的所有字符
		Pop(st,e);					//退栈元素e
		if(str[i]!=e)				//若e与当前串字符不同,说明不是对称串
		{
			DestroyStack(st);
			return false;	
		} 
		DestroyStack(st);			//销毁
		return true; 
	}
}

共享栈


在这里插入图片描述
在这里插入图片描述

typedef struct{
	ElemType data[MaxSize];		//存放共享栈中的元素
	int top1,top2;				//两个栈的栈顶指针 
}DStack;

链栈

  • 定义

栈中数据元素的逻辑关系呈线性关系,所以栈可以像线性表一样采用链式存储结构。采用链式存储结构的栈称为链栈

  • 声明
typedef struct linknode{
	ElemType data;				//数据域
	struct linknode * next;		//指针域 
}LinkStNode;					//链栈结点类型
 
  • 初始化栈
void InitStack(LinkStNode * &s){
	s = (LinkStNode * )malloc(sizeof(LinkStNode));
	s->next = NULL;
}

在这里插入图片描述

  • 销毁栈
void DestroyStack(LinkStNode * &s){
	LinkStNode * pre = s,*p = s->next;	//pre指向头结点,p指向首结点
	while(p != NULL){					//循环到p为空
		free(pre);						//释放pre结点 
		pre = p;						//pre、p同步后移 
		p = pre->next; 
	} 
	free(pre);
} 
  • 判断栈是否为空
bool StackEmpty(LinkStNode * s){
	return(s->next == NULL);
}
  • 进栈
void Push(LinkStNode * &s,ElemType e){
	LinkStNode * p;
	p = (LinkStNode *)malloc(sizeof(LinkStNode));	
	p->data = e;						
	p->next = s->next;					//将p结点插入作为首结点
	s->next = p ; 
}
  • 出栈

在这里插入图片描述

bool Pop(LinkStNode * &s,ElemType &e){
	LinkStNode *p;
	if(s->next == NULL)		//栈空情况 
		return false;
	p = s->next;			//p指向首结点
	e = p->data;			//提取首结点值
	s->next = p->next;		//删除首结点
	free(p);				//释放被删结点的存储空间
	return true; 
}
  • 取栈顶元素
bool GetTop(LinkStNode 8 s,ElemType &e){
	if(s->next == NULL){
		return false;
	}
	e = s->next->data;
	return false;
}
  • 应用

在这里插入图片描述

bool Match(char exp[],int n){
	int i = 0;char e;
	bool match = true;
	LinkStNode * st;
	InitStack(st);					//初始化链栈
	while(i<n && match){			//扫描exp中的所有字符 
		if(exp[i] == '(')			//当前字符为左括号,将七进栈
			Push(st,exp[i]);
		else if(exp[i] == ')')		//当前字符为右括号
		{
			if(GetTop(st,e) == true){//成功取栈顶元素e
				if(e !='('){
					metch = false;		//当栈顶元素不为(时,表示不匹配 
				}
				else{
					Pop(st,e);			//当扎顶元素为(时,将栈顶元素出栈 
				} 
			}	
		}
		i++;							//继续处理其他字符
	}
	if(!StackEmpty(st)) 				//栈不为空时表示不匹配 
		match = false;
	DestroyStack(st);					//销毁栈
	return match; 
}

在这里插入图片描述

队列

定义

在这里插入图片描述

顺序队

  • 声明队列
typedef struct{
	ElemType data[MaxSize];
	int front,rear;				//队头和队尾指针 
}SqQueue;
  • 初始化队列
void InitQueue(SqQueue * &q){
	q = (SqQueue *)malloc(sizeof(SqQueue));
	q->front = q->rear =-1;
}
  • 销毁队列
void DestroyQueue(SqQueue * &q){
	free(q);
}
  • 判断队列是否为空
bool QueueEmpty(SqQueue * &q){
	return(q->front == q->rear);
}
  • 进队
bool enQueue(SqQueue * &q,ElemType e){
	if(q->rear == MaxSize-1)	//队满上溢出
		 return false;
		q->rear++;				//队尾增1
		q->data[q->rear] = e;	//rear位置插入元素e
		return true; 
}
  • 出队
bool deQueue(SqQueue * &q,ElemType &e){
	if(q->front == q->rear)		//队空下溢出
		return false;
	q->front++;
	e = q->data[q->front];
	return true; 
}

环形队

  • 定义
    在这里插入图片描述
    在这里插入图片描述

  • 初始化队列

void InitQueue(SqQueue * &q){
	q = (SqQueue *)malloc(sizeo(SqQueue));
	q->front = q->rear = 0;
}
  • 销毁队列
void DestroyQueue(SqQueue * &q){
	free(q);
}
  • 判断队列是否为空
bool QueueEmpty(SqQueue * q){
	return(q->front == q->rear);
}
  • 进队列
bool enQueue(SqQueue * &q,ElemType e){
	if((q->rear+1)%MaxSize == q->front)	//队满上溢出
		 return false;
	q->rear=(q->rear+1)%MaxSize;	//队尾增1
	q->data[q->rear] = e;			//rear位置插入元素e
	return true; 
}
  • 出队列
bool deQueue(SqQueue * &q,ElemType &e){
	if(q->front == q->rear)		//队空下溢出
		return false;
	q->front = (q->front+1)%MaxSize;
	e = q->data[q->front];
	return true; 
}

链队

  • 声明

链队中数据结点声明:

typedef struct qnode{
	ElemType data;			
	struct qnode * next;
}DataNode;

链队头结点声明:

typedef struct{
	DataNode * front;
	DataNode * rear;
}LinkQuNode; 
  • 初始化
void InitQueue(LinkQuNode * &q){
	q=(LinkQuNode * )malloc(sizeof(LinkQuNode));
	q->front = q->rear = NULL;
}
  • 销毁队列
void DestroyQueeu(LinkQuNode * &q){
	DataNode *pre = q->front,*p;			//pre指向队首结点
	if(pre!=NULL){
		p = pre->next;						//p指向pre的后继结点 
		while(p!=NULL){
			free(pre);
			pre = p;p = p->next;			//pre、p同步后移				
		}
		free(pre);			//释放最后一个数据结点 
	}
	free(q); 				//释放链队结点 
}
  • 判断队列是否为空
bool QneneEmpty(LinkQuNode * q){
	return(q->rear == NULL);
}
  • 进队列
void enQueue(LinkQuNode * &q,ElemType e){
	DataNode *p;
	p = (DataNode *)malloc(sizeof(DataNode));		//创建新结点
	p->data = e;
	p->next = NULL;
	if(q->rear == NULL)								//若链队为空,则新结点既是队首结点又是队尾结点 
		q->front = q->rear = p;
	else{											//若链队不为空 
		q->rear->next = p;							//将结点p链到队尾,并将rear指向它
		q->rear = p; 
	}
}
  • 出队列
bool deQueue(LinkQuNode * &q,ElemType &e){
	DataNode *t;
	if(q=>rear == NULL)				//原来队列为空 
		return false;
	t = q->front;					//t指向首结点
	if(q->front == q->rear)			//原来队列中只有一个数结点时
		q->front = q->rear = NULL;
	else							//原来队列中有两个或两个以上结点时
		q->front = q->front->next;
	e = t->data; 
	free(t);
	return true;	 
}
  • 应用

在这里插入图片描述

void number(int n){
	int i;ElemType e;
	SqQueue *q;						//环形队列指针q
	InitQueue(q);					//初始化队列q
	for(i = 1;i<=n;i++)				//构建初始序列
		enQueue(q,i);
	printf("报数出列顺序:");
	while(!QueueEmpty(q)){			//队列不空循环
		deQueue(q,e);				//出队一个元素e
		printf("%d",e); 			//删除元素编号
		if(!QueueEmpty(q))			//队列不空
		{
			deQueue(q,e);			//出队一个元素e 
			enQueue(q,e);			//将刚出队的元素进队	
		}
		printf("\n");
		DestroyQueue(q);			//销毁队列q 
	}
}

int main(){
	int i,n = 8;
	printf("初始序列:");
	for(i = 1;i<=n;i++)
		printf("%d",i);
	prinf("\n");
	number(n);
	return 1;
}

没看懂!

双端队列

在这里插入图片描述
在这里插入图片描述

  • 实现“从队尾删除”运算的算法如下:
bool deQueuel(SqQueue * &q,ElemType &e){		//从队尾删除算法
	if(q->front == q->rear)		//队空返回假 
		return false; 
	e = q->data[q->rear];		//提取队尾元素
	q->rear = (q->rear-1+MaxSize)%MaxSize;	//修改队尾指针
	return true;	
} 
  • 实现“从队头插入”运算的算法如下:
bool enQueuel(SqQueue * &q,ElemType e){
	if((q->rear + 1)%MaxSize == q->front)		//队满返回假 
		return false;
	q->data[q->front] = e;						//元素e进队
	q->front = (q->front-1+MaxSize)%MaxSize;	//修改队头指针 
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值