栈和队列

栈和队列(一)


()
在这里插入图片描述
从图 我们看到,栈存储结构与之前所学的线性存储结构有所差异,这缘于栈对数据 “存” 和 “取” 的过程有特殊的要求:
(1)栈只能从表的一端存取数据,另一端是封闭的,如图 1 所示;
(2)在栈中,无论是存数据还是取数据,都必须遵循"先进后出"的原则,即最先进栈的元素最后出栈。拿图 1 的栈来说,从图中数据的存储状态可判断出,元素 1 是最先进的栈。因此,当需要从栈中取出元素 1 时,根据"先进后出"的原则,需提前将元素 3 和元素 2 从栈中取出,然后才能成功取出元素 1。

因此,我们可以给栈下一个定义,即栈是一种只能从表的一端存取数据且遵循 “先进后出” 原则的线性存储结构。

通常,栈的开口端被称为栈顶;相应地,封口端被称为栈底。因此,栈顶元素指的就是距离栈顶最近的元素,拿图 2 来说,栈顶元素为元素 4;同理,栈底元素指的是位于栈最底部的元素,图 2 中的栈底元素为元素 1。

在这里插入图片描述

进栈和出栈

基于栈结构的特点,在实际应用中,通常只会对栈执行以下两种操作:
向栈中添加元素,此过程被称为"进栈"(入栈或压栈);
从栈中提取出指定元素,此过程被称为"出栈"(或弹栈)

顺序栈

//栈
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
#define MaxSize 100
typedef struct{
	ElemType data[MaxSize];
	int top;
}SeqStack; 
//置空栈 
SeqStack *InitStack(){
	SeqStack *s;
	s=(SeqStack *)malloc(sizeof(SeqStack));
	s->top =-1;
	return s;
}
//判空栈
int Empty(SeqStack *s){
	if(s->top ==-1)
		return 1;
	return 0;
} 
//入栈
int Push(SeqStack *s,ElemType x){
	if(s->top == MaxSize-1)
		return 0;     //栈满不能入栈
	else{
		s->data[++(s->top )]=x;
		return 1; 
	} 
} 
//出栈 
int Pop(SeqStack *s,ElemType *x){
	if(Empty(s) )
		return 0;  //栈空不能出栈
	 else{
	 	*x=s->data[s->top --];
	 	return 1;
	 }
	
}
//取栈顶元素
ElemType GetTop(SeqStack *s){
	if(Empty(s))
		return 0;
	else
	{
		return(s->data [s->top ]);
	}
} 
int main(){
	SeqStack *s=InitStack();
	printf("%d\n",Empty(s));
	int a=1,b=2;
	printf("%d\n",Push(s,a));
	printf("%d\n",Push(s,b));
	int *x;
	x=(int *)malloc(sizeof(int));
	Pop(s,x);
	printf("%d",*x);
	
}

顺序栈(共享)

//多栈共享邻接空间
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
#define MaxSize 100
typedef struct{
	ElemType data[MaxSize];
	int Ltop;
	int Rtop;
}DupStack;
//初始化操作 
DupStack *InitDupStack(){
	DupStack *s;
	//创建两个共享邻接空间的空栈由指针s指出
	if((s=(DupStack *)malloc(sizeof(DupStack)))==NULL)
		return NULL;//指针开辟空间失败
	s->Ltop =-1;
	s->Rtop =MaxSize;
	return s; 
}
//入栈操作
int PushDupStack(DupStack *s,char status,ElemType x){
	//把数据压入左栈或者右栈
	if(s->Ltop +1==s->Rtop ){
		printf("栈满"); 
		return -1;//栈满
		}
	else if(status=='L'){
		 s->data[++s->Ltop ]=x;	
	}
	else if(status=='R')
		 s->data[--s->Rtop ]=x;
	else
		return -1;
	return 1;
}
//出栈操作
ElemType PopDupStack(DupStack *s,char status){
	//从左栈(status=='L')或者右栈(status=='R')退出栈顶元素
	if(status == 'L')
	{
		if(s->Ltop  <0) return NULL;  //左栈为空
		else return(s->data[s->Ltop --]);	
	}
	else if(status == 'R'){
		if(s->Rtop>MaxSize-1 ) return NULL;// 右栈为空
		else return(s->data[s->Rtop++ ]); 
	}
	else return NULL;//参数错误 
} 
int main(){
	DupStack *s;
	s=InitDupStack();//初始化;
	int a=1,b=2;
	char L='L',R='R';
	PushDupStack(s,L,a);
	PushDupStack(s,L,b);
	PushDupStack(s,R,b);
	PushDupStack(s,R,a);
    printf("%d",PopDupStack(s,R));	 
}

链栈

//链栈
#include<stdio.h>
#include<stdlib.h>
typedef struct StackNode{
	int data;
	struct StackNode *next;
}slStacktype;
//入栈
int PushStack(StackNode *top,int x){
	StackNode *p;
	p=(StackNode *)malloc(sizeof(StackNode));
	p->next =NULL;
	if(!p)
		return -1;
	p->data =x;
	p->next =top->next ;
	top->next = p;
	return 1;
}
//出栈
int PopStack(slStacktype *top)
{
	slStacktype *p;
	int x;
	if(!top->next )	
	{
		printf("空栈");
		return -1;
	}
	p=top->next ;
	top->next =p->next ;
	x=p->data ;
	free(p);
	return x;
} 
int main()
{
	StackNode *top=(StackNode *)malloc(sizeof(StackNode));
	top->next =NULL;
	int x=5;
	int n=PushStack(top,x);
	printf("%d\n",n);
	printf("%d",PopStack(top));
}

环队

增设tag数据成员以区分队满还是队空

tag表示0的情况下,若因删除导致front==rear,则队空;

tag等于1的情况,若因插入导致front==rear则队满

//队列(循环队列防止假溢出)
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct{
	ElemType elem[MAXSIZE];
	int rear;		 //队尾
	int front;		 //队头 
	int tag;         //判断队空与队满 
}CSeQueue;
//置空队
CSeQueue *InitSeQueue(){
	CSeQueue *q;
	q=((CSeQueue *)malloc(sizeof(CSeQueue)));
	q->front =q->rear =MAXSIZE-1;
	return q;
} 
//入队
int InSeQueue(CSeQueue *q,ElemType x){
	if((q->rear +1)%MAXSIZE==q->front )//队满不能入队
	{
		printf("队满");
		return -1; 
	} 
	else{
		q->rear =(q->rear +1)%MAXSIZE;
		q->elem [q->rear ]=x;
		q->tag=1; 
		return 1;   //成功入队 
	}
} 
//出队
int OutSeQueue(CSeQueue *q,ElemType *x){
	if(q->front ==q->rear )
	{
		printf("队空");
		return -1; 
	}
	else
	{
		q->front =(q->front +1)%MAXSIZE;
		*x=q->elem [q->front ];
		q->tag =0;
		return 1 ;// 出队成功 
	}
} 
//判队空
int EmptySeQueue(CSeQueue *q){
	if(q->front ==q->rear&&q->tag==0 ) 
		return 1;
	return -1;
} 
int main(){
	
}
 

链队

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值