数据结构和算法(三):栈和队列

栈——后进先出

表的一段进行插入和删除的操作

栈的顺序存储

静态顺序栈

用一维数组存储,栈底不变,栈顶指针top(整型变量)指向当前栈顶的位置
在这里插入图片描述

定义
#define MAX_STACK_SIZE 100
#typedef int ElemType;
typedef struct sqstack
{
	ElemType stack_arry[MAX_STACK_SIZE];
	int top;
}SqStack;
初始化
SqStack Init_Stack(void)
{
	SqStack S;
	S.bottom=S.top=0;
	return(s);
}
出栈
Status pop(SqStack &S,ElemType &e)
{
	if(S.top==0)
	return ERROR;//栈空,返回错误
	*e=S.stack_array[S.top];
	S.top--;
	return OK;
}
入栈
Status push(SqStack&S,ElemType &e)
{
	if(S.top==MAX_STACK_SIZE-1)
	return ERROR;//栈满,因为是从0开始计数的
	S.top++;
	S.stack_array[S.top]=e;
	return OK;
}

动态顺序栈

top指向栈顶的下一个存储位置在这里插入图片描述

定义
#define STACK_SIZE 100//栈的初始向量的大小
#define STACKINCREMENT 10//存储空间分配的增量
#typedef int ElemType;
typedef struct sqstack
{
	ElemType *bottom;//栈不存在时为NULL
	ElemType *top;//栈顶指针
	int stacksize;
}SqStack;
初始化
Status Init_Stack(void)
{
	SqStack S;
	S.bottom=(ElemType*)malloc(STACK_SIZE*sizeof(ElemType));
	if(!S.bottom)
		return ERROR;
	S.top=S.bottom;//令栈顶和栈底指针相同
	S.stacksize=STACK_SIZE;
	return OK;
}

出栈(弹栈)
pop(SqStack &S,ElemType &)
{
	if(S.top==S.bottom)
		return ERROR;
	S.top--;//因为top始终指向栈顶的下一个
	e=*S.top;
	return OK;
}
入栈
Status push(SqStack &S,ElemType e)
{
	if(S.top-S.bottom>=S.stacksize-1)
	{
		S.bottom=(ElemType*)realloc((S.STACKINCREMENT+STACK_SIZE)*sizeof(ElemType));
		if(!S.bottom)
			return ERROR;
		S.top=S.bottom+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top=e;
	S.top++;
	return OK;
}

栈的链式存储

栈顶指针top是链表的头指针
在这里插入图片描述

栈的结点类型说明

typedef struct Stack_Node
{
	ElemType data;
	structStack_Node *next;
}Stack_Node;

栈的初始化

Stack_Node*Init_Link_Stack(void)
{
	Stack_Node*top;
	top=(Stack_Node*)malloc(sizeof(Stack_Node);
	top->next=NULL;
	return(top)
}

出栈(弹栈)

Status pop(Stack_Node *top,ElemType *e)
{
	Stack_Node *p;
	ElemType e;
	if(top->next==NULL)
		return ERROR;
	p=top->next;
	e=p->data;
	top->next=p->next;
	free(p);
	return OK;
}

压栈

Status push(Stack_Node*top,ElemType)
{
	Stack_Node *p;
	p=(Stack_Node*)malloc(sizeof(Stack_Node));
	if(!p)
		return ERROR;
	p->data=e;
	p->next=top->next;
	top->next=p;
	return OK;
}

队列——先进先出

在这里插入图片描述

基本概念

队列Queue
队首front:允许进行删除的一端
队尾rear:允许进行插入的一段

队列的顺序结构

表示

#define MAX_QUEUE_SIZE 100;
typedef struct queue
{
	ElemType Queue_array[MAX_QUEUE_SIZE];
	int front;
	int rear;
}SqQueue;

初始化:front=rear=0
入队:将新元素插入rear所指的的位置,然后rear加1
出队:删去front所指的元素,然后加1并返回被删元素
队列为空:front=rear
队满:rear=MAX_QUEUE_SIZE-1

存在假溢出现象
在这里插入图片描述

循环队列

在这里插入图片描述循环队列为空:front=rear
循环队列满:(rear+1)%MAX_QUEUE_SIZE=front

初始化
SqQueue Init_CirQueue(void)
{
	SqQueue Q;
	Q.front=Q.rear=0;
	return (Q);
}
入队
Status Insert_CirQueue(SqQueue &Q,ElemType e)
{
	if((Q.rear+1)%MAX_QUEUE_SIZE==Q.front)
		return ERROR;
	Q.Queue_array[Q.rear]=e;
	Q.rear=(Q.rear+1)%MAX_QUEUE_SIZE;//队尾指针加1
		return OK;
}
出队
Status Delete_CriQueue(SqQueue &Q,ElemType *x)
{
	if(Q.front==Q.rear)
		return ERROR;
	*x=Q.Queue_array[Q.front];
	Q.front=(Q.front+1)%MAX_QUEUE_SIZE;//队首指针向前移动
	return OK;
}

队列的链式存储结构

在这里插入图片描述

数据元素结点的类型定义

typedef struct Qnode
{
	ElemType data;
	struct Qnode *next;
}QNode;

链队列初始化

LinkQueue *Init_LinkQueue(void)
{
	LinkQueue *Q;
	QNode *p;
	p=(QNode*)malloc(sizeof(QNode));//开辟头结点
	p->next=NULL;
	Q=(LinkQueue*)malloc(sizeof(LinkQueue));//开辟链队的指针结点
	Q.front=Q.rear=p;
	return (Q);
}

入队

将数据元素e插入到链队列的Q的队尾

Status Insert_CriQueue(LinkQueue *Q,ElemType e)
{
	p=(QNode*)malloc(sizeof(QNode));
	if(!p)//申请空间失败
		return ERROR;
	p->data=e;
	p->next=NULL;//先勾右边
	Q.rear->next=p;//再勾左边
	Q.rear=p;
		return OK;
}

出队

Status Delete_LinkQueue(LinkQueue *Q,ElemType *x)
{
	QNode*p;
	if(Q.front==Q.rear)//队空
		return ERROR;
	p=Q.front->next;//取队首结点
	*x=p->data;
	Q.front->next=p->next;//修改首指针
	if(p==Q.rear)
		Q.rear=Q.front;
	free(p);
	return OK
}

队列的撤销

将链队Q 的队首元素依次出队

void Destory_LinkQueue(LinkQueue *Q)
{
	QNode*p=NULL;
	if(Q.front)p=Q.front->next;
	while(p->next)
	{
		QNode *q=p->next;
		free(p);
		p=q;
	}
	Q.front->next=NULL;
	Q.rear=Q.front;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值