DataStructure_4.Stack Queue

2024-03-09 09:58
文章标签 stack queue datastructure

本文主要是介绍DataStructure_4.Stack Queue,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

4.1 栈的定义

4.1.1 限定仅在表层进行插入和删除操作的线性表。允许插入和删除的的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈。栈可以形象地表述为后进先出(Last In First Out)的线性表,简称LIFO结构。

需要明白的是,栈结构只是限定了线性表插入和删除的位置必须在栈顶,但没有对元素进出的时间做限制,只需要保证是栈顶元素出栈就行。

例如:将a,b,c依次压入栈,可以先把a压进,然后a弹出,再压b,然后弹出b。最后压c,再弹c。这样出栈次序为abc。所以说明,不一定最先进栈的元素只能最后出栈。

4.1.2栈的结构定义

typedef int SElemType;

typedef struct{

SElemType data[MaxSize];

int top;//由于是依托数组,所以顺序存储结构的栈顶指针类型为整型,存放数组下标,思路同静态链表

}SqStack

4.2 栈的顺序存储结构

4.2.1 当栈存在一个元素时,top中存储的下标为0,而空栈时top中存储的应为-1,而且top中存储的下标必须小于存储站的长度StackSize

4.2.2 push操作-时间复杂度O(1)

Status Push(SqStack *S, Selemtype e){

if(s->top==MaxSize-1){//栈满的情况

return ERROR;

}

S->top++ //栈顶指针增加1

S->data[S->top]=e//将要入栈的元素赋值给栈顶空间

return OK;

}

4.2.3 pop操作-时间复杂度O(1)

Status Pop(SqStack* S, SElemType *e){

if(S->top==-1) return ERROR;

*e=S->data[S->top];//将要删除的栈顶元素赋值给e(用作弹出)

S->top--; //栈顶指针减1

return OK;

}

4.2.4两栈共享空间

栈的顺序存储结构相对与线性表的顺序存储结构优势在于不需要再删除或插入时移动元素,但自身缺陷在于数组大小必须事先确定,如果不确定那么到时候不够的话会很麻烦。这是针对只有一个栈的情况;当有两个相同的栈时,我们完全可以用一个数组来存储这两个栈。形象的来说就是两个栈分别以一个数组的两端点为栈底,如果增加元素就都向数组中间延伸。只要栈1和栈2的栈顶指针不相遇就能在一个数组中一直使用这两个栈。

易得:栈1为空即为top1==-1,栈2为空即为top2==n,当两指针见面而不重叠时(top1+1==top2)即为栈满

typedef struct{

SElemTypedata[MaxSize];

int top1;

int top2;

}SqDoubleStack;

//判断栈号参数stackNumber

Status Push(SqDoubleStack *S, SElemType e, int stackNumber){

if(S->top1+1==S->top2)//满栈了

return ERROR;

if(stackNumber==1) S->data[++S->top1]=e;//top1+1后给数组元素赋值

else if(stackNumber==2) S->data[--S->top2]=e;//top2-1后给数组元素赋值

return OK;

}//由于之前已经判断了是否满栈的情况,所以后面的top1+1top2-1不用担心溢出

注意:两栈共享空间在数据为反比例关系的时候会很方便,即一方增长另一方减少。

Status Pop(SqDoubleStack *S, SElemType e, int stackNumber){

if(stackNumber==1){

if(S->top1==-1) return ERROR;//1已经空了,溢出

*e=S->data[S->top1--];//将栈1的栈顶元素出栈

}

else if(stackNumber==2){

if(S->top1==MaxSize) return ERROR;//2已经空了,溢出

*e=S->data[S->top2++];//将栈2的栈顶元素出栈

}

return OK;

}

4.3 栈的链式存储结构

4.3.1

顺序栈适用于元素变化可控情况,如果元素变化无常,时大时小(说实话这么写有点绕,所以只要明白链栈不会爆就是了),就使用链栈。

把栈顶放在单链表的头部,同时舍去头结点。

链栈基本不存在栈满的情况,满了说明内存爆了那就当机了。对于空栈,头指针指向空换算成链栈的情况就是top=NULL

typedef struct StackNode{

SElmType data;

struct StackNode *next;

}StackNode,*LinkStackPtr;

  

typedef struct LinkStack{

LinkStackPtr top;

int count;

}LinkStack;

链栈操作绝大部分都和单链表类似,只是在插入和删除上特殊一些。

4.3.2 进栈操作-时间复杂度O(1)

Status Push(LinkStack *Sk, SElemType e){

LinkStackPtr s=(LinkStackPtr) malloc(sizeof(StackNode));

s->data=e;//把要插入的元素值赋给数据域

s->next=Sk->top;//把当前的栈顶元素赋值给新结点的直接后继

Sk->top=s;//将新的结点s赋值给栈顶指针

Sk->count++;

return OK;

}

4.3.3出栈操作-时间复杂度O(1)

Status Pop(LinkStack *Sk, SElemType e){

LinkStackPtr p;

if(StackEmpty(*Sk)) return ERROR;

*e=Sk->top->data;

p=Sk->top;//将栈顶结点赋值给p

Sk->top=Sk->top->next;//使得栈顶指针下移一位,指向后一结点

free(p);//释放结点p

Sk->count--;

return OK;

}

4.4 队列的定义

4.4.1 队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表,与栈不同的是遵从先进先出(First In First Out),FIFO结构。允许插入的一端称为队尾,允许删除的一端称为队头(联想现实情况排队,后到的排在队尾)典型的就是键盘输入到鼠标屏幕上,先按下的键肯定先显示出来,这就是使用队列结构。

4.4.2 由于顺序存储结构在队列的出队实现中既耗费时间(O(n))还容易出现假溢出(队头还有空间结果队尾满了进不去了)所以将队列的头尾连接起来,称为循环队列。

//循环队列的顺序存储结构

typedef int QElemType;

typedef struct{

QElemType data[MaxSize];

int front;//队头指针

int rear;//队尾指针,若队列不空,指向队尾元素的下一位置

}SqQueue;

//初始化

Status InitQueue(SqQueue *Q){

Q->front=0;

Q->rear=0;

return OK;

}

//求队列长度

int QueueLength(SqQueue Q){

return (Q.rear-Q.front+MaxSize)%MaxSize;//通用队列长度计算公式p116

}

//入列

Status EnQueue(SqQueue *QQElemType e){

if((Q->rear+1)%MaxSize==Q->front) return ERROR;//判断是否已满

Q->data[Q->rear]=e;//要入列的元素e赋值给队尾

Q->rear=(Q->rear+1)%MaxSize;//rear指针向后移动一位置,若到最后则转为数组头部

return OK;

}

//出列

Status EnQueue(SqQueue *QQElemType e){

if((Q->front==Q->rear) return ERROR;//判断队列空

*e=Q->data[Q->front];//将队头元素赋值给e

Q->front=(Q->front+1)%MaxSize;//front指针向后移动一位置,若到最后则转为数组头部

return OK;

}

4.4.3 链式存储结构-链队列

队头指针指向链队列的头结点,队尾指针指向终端结点,空队列时队头尾指针都指向头结点

typedef int QElemType;

typedef struct QNode{

QElmType data;

struct QNode *next;

}QNode,*QueuePtr;

  

typedef struct{

QueuePtr front,rear;

}LinkQueue;

//入列

Status EnQueue(LinkQueue *QQElemType e){

QueuePtr s=(QueuePtr) malloc(sizeof(QNode));

if(!s) exit(OVERFLOW);//分配失败

s->data=e;//要入列的元素e赋值给队尾

s->next=NULL;

Q->rear->next=s;//新结点s赋值给原队尾结点的后继

Q->rear=s;//设置s为新的队尾结点

return OK;

}

//出列,就是头结点的后继结点出列,若除头结点只剩一个结点,则需将rear指向头结点

Status DeQueue(LinkQueue *QQElemType *e){

QueuePtr P;

if(Q->front==Q->rear) return ERROR;//队列已空

p=Q->front->next;//要删除的结点由p牵引

e=p->data;//要删除的结点数据赋值给e

Q->front->next=p->next;//将原队头结点后继p->next赋值给头结点后继

if(Q->rear==p) Q->rear=Q->front;//如果队头是队尾,则删除后将rear指向头结点

free(p);

return OK;

}

 

这篇关于DataStructure_4.Stack Queue的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/790322

相关文章

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现

ActiveMQ—Queue与Topic区别

Queue与Topic区别 转自:http://blog.csdn.net/qq_21033663/article/details/52458305 队列(Queue)和主题(Topic)是JMS支持的两种消息传递模型:         1、点对点(point-to-point,简称PTP)Queue消息传递模型:         通过该消息传递模型,一个应用程序(即消息生产者)可以

Java-数据结构-栈和队列-Stack和Queue (o゚▽゚)o

文本目录: ❄️一、栈(Stack):     ▶ 1、栈的概念:   ▶ 2、栈的使用和自实现:      ☑ 1)、Stack():       ☑ 2)、push(E e):      ☑ 3)、empty():         ☑ 4)、peek(E e):        ☑ 5)、pop(E e):       ☑ 6)、size(E e):  ▶ 3、栈自实现的总代

c++stack和list 介绍

stack介绍 堆栈是一种容器适配器,专门设计用于在 LIFO 上下文(后进先出)中运行,其中元素仅从容器的一端插入和提取。 堆栈作为容器适配器实现,容器适配器是使用特定容器类的封装对象作为其基础容器 的类,提供一组特定的成员函数来访问其元素。元素从特定容器的 “back” 推送或弹出,这称为堆栈的顶部。 stack接口 stack() 构造空的栈 empty() 检测stack是否为

stack,queue, priority_queue

STL 中栈的使用方法(stack) #include <stack> 基本操作: push(x) 将x加入栈中,即入栈操作 pop() 出栈操作(删除栈顶),只是出栈,没有返回值 top() 返回第一个元素(栈顶元素) size() 返回栈中的元素个数 empty() 当栈为空时,返回 true STL 中队列的使用(queue) #i

HDU 1297 Children’s Queue

题目: http://acm.hdu.edu.cn/showproblem.php?pid=1297 题解: D[n]表示有n个人时,满足排队要求的个数。 分类讨论: 1.第n个人为男生时,满足排队要求的个数等于D[n-1]. 2.第n个人为女生时,第n-1个必为女生,才满足要求。 此处还要进行一次分类: a.前n-2个满足排队要求时,个数为D[n-2]. b.前n-2个不满足

Elastic Stack--ES集群加密及Kibana的RBAC实战

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 学习B站博主教程笔记:  最新版适合自学的ElasticStack全套视频(Elk零基础入门到精通教程)Linux运维必备—ElasticSearch+Logstash+Kibana精讲_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1VMW3e6Ezk/?sp

C++ STL-Stack容器概念及应用方法详解

1. 再谈栈 栈是一种先进后出的数据结构,而实现方式需要创建多个结构体,通过链式的方式进行实现,这是标准的栈的思路,而在STL中栈可以以更为简单的方式实现。 概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口。 栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为。 栈中进入数据称为 — 入栈 push 栈中弹出数据称为 — 出

C++ STL-Queue容器概念及应用方法详解

1. 再谈队列 队列和栈不同,队列是一种先进先出的数据结构,STL的队列内容极其重要,虽然内容较少但是请务必掌握,STL的队列是快速构建搜索算法以及相关的数论图论的状态存储的基础。 概念:Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口。 队列容器允许从一端新增元素,从另一端移除元素。队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历

ORA-24067: exceeded maximum number of subscribers for queue ADMIN.SMS_MT_QUEUE

临时处理办法: delete from aq$_ss_MT_tab_D;delete from aq$_ss_MT_tab_g;delete from aq$_ss_MT_tab_h;delete from aq$_ss_MT_tab_i;delete from aq$_ss_MT_tab_p;delete from aq$_ss_MT_tab_s;delete from aq$