首页 > 编程语言 >【技术积累】数据结构中栈与队列及其相关算法【一】

【技术积累】数据结构中栈与队列及其相关算法【一】

时间:2023-07-09 23:33:05浏览次数:34  
标签:队列 top 元素 栈顶 中栈 queue 数据结构 stack

什么是栈

栈是一种特殊的数据结构,它的各个元素按照一定的次序排列,且只能在表的一端(称为栈顶)进行添加和删除数据,这种数据结构遵循后进先出(LIFO)的原则。栈可以简单地理解为一种容器,它在使用时非常方便,因为只需在顶部压入(push)或弹出(pop)元素即可。

栈可以直接使用数组或链表等数据结构来实现。在程序执行中,栈最常见的应用场景是函数调用。每当一个函数被调用,它将会被压入栈中。当函数的执行完成时,它又会从栈中弹出。在这种情况下,栈可以帮助计算机留存执行函数的上下文信息。栈还可以用于中断回调、表达式求值、递归、括号匹配等。

栈顶和栈底分别指向位置固定的两个元素,通常认为栈底是位置固定的元素,而顶部是最近添加的元素。当栈为空时,栈顶和栈底指向同一个位置。在栈中还有一些常用操作,如查看栈顶元素(top)和判断栈是否为空等。实现这些操作的时间复杂度都是O(1)。

什么是队列

队列是一种先进先出(FIFO)的线性数据结构,它的元素按照一定的顺序排列,只允许在队尾添加元素,在队头删除元素。队列通常用于存储按顺序排列的数据。

队列可以简单地比喻为一个管道,元素从一端进入(enqueue),从另一端出去(dequeue)。队列的实现一般使用数组或链表,其中数组实现的队列叫作顺序队列,链表实现的队列叫作链式队列。

队列也有一些常见的操作,如查看队头元素(peek)、获取队列长度(size)和判断队列是否为空等。这些操作的时间复杂度都是O(1)。

队列应用的场景非常广泛。在计算机系统中,排队等待的请求往往被组织成一个队列,例如打印作业、进程调度、网络中的传输请求等。在算法实现中,广度优先遍历(BFS)中就使用了队列。同时,队列还可以被用于生产者消费者问题,即一个线程生产数据并放入队列,另一个线程从队列中取出数据并消费。

栈与队列的联系和区别

栈和队列是两种基本的线性数据结构,它们都具有一些共同的特点,同时也有着不同的用途和实现方式。

1. 相同点

(1)都是数据通路为一条直线的线性结构;

(2)都支持两种基本操作:入栈(入队)和出栈(出队);

(3)都可以用数组或链表实现;

(4)都可以用于实现计算机算法和程序设计中的各种逻辑结构;

2. 区别

(1)入队和入栈的区别:

入队是将元素插入到队列的尾部;

入栈是将元素插入到栈顶;

(2)出队和出栈的区别:

出队是从队列的头部删除一个元素;

出栈是删除栈顶的元素;

(3)特性上的区别:

栈是一种后进先出(LIFO,Last In First Out)的数据结构;

队列是一种先进先出(FIFO,First In First Out)的数据结构;

(4)用途的区别:

栈的主要应用场景是在程序中进行函数调用、表达式求值和内存管理等方面;

队列的主要应用场景是在程序中进行任务调度、消息处理和缓存等方面。

总之,栈和队列都是重要的线性数据结构,具有不同的特性和应用场景,程序设计者需要根据不同的需求选择合适的数据结构来实现算法和数据管理。

栈与队列的操作

栈与队列都是常用的数据结构,它们都有自己独特的特点和操作,下面分别介绍栈与队列的操作。

栈的操作

栈是一种后进先出(Last In First Out)的数据结构,只能对最后插入的元素进行访问和操作,操作如下:

1. 入栈(Push):向栈顶插入一个元素,栈顶指针向上移动。

2. 出栈(Pop):删除栈顶元素,栈顶指针向下移动。

3. 取栈顶元素(Top):返回栈顶元素的值,不改变栈的结构。

4. 判断栈是否为空(IsEmpty):当栈中没有任何元素时,返回真。

队列的操作

队列是一种先进先出(First In First Out)的数据结构,只能对最早插入的元素进行访问和操作,操作如下:

1. 入队(Enqueue):向队尾插入一个元素,队尾指针向上移动。

2. 出队(Dequeue):删除队头元素,队头指针向下移动。

3. 取队头元素(Front):返回队头元素的值,不改变队列的结构。

4. 取队尾元素(Rear):返回队尾元素的值,不改变队列的结构。

5. 判断队列是否为空(IsEmpty):当队列中没有任何元素时,返回真。

以上是栈与队列的基本操作,不同的应用场景会有相应的操作扩展。

如何实现入栈,出栈,入队,出队

入栈操作

1.将要入栈的元素压入栈顶
2.栈顶指针加1

伪代码:

procedure push(stack, element)
    if stack.is_full():
        error("stack overflow")
    else:
        stack.top = stack.top + 1
        stack[stack.top] = element

出栈操作

1.取出栈顶元素
2.栈顶指针减1

伪代码:

procedure pop(stack)
    if stack.is_empty():
        error("stack underflow")
    else:
        element = stack[stack.top]
        stack.top = stack.top - 1
        return element

入队操作

1.将要入队的元素加入队尾
2.队尾指针加1

伪代码:

procedure enqueue(queue, element)
    if queue.is_full():
        error("queue overflow")
    else:
        queue.tail = queue.tail + 1
        queue[queue.tail] = element

出队操作

1.取出队头元素
2.队头指针加1

伪代码:

procedure dequeue(queue)
    if queue.is_empty():
        error("queue underflow")
    else:
        element = queue[queue.head]
        queue.head = queue.head + 1
        return element

判断栈与队列是否为空

栈和队列的判断操作描述如下:

判断栈是否为空

  • 如果栈顶指针等于-1,说明栈为空,返回true
  • 否则,栈不为空,返回false。
function isStackEmpty(stack):
    if stack.top == -1:
        return true
    else:
        return false

判断栈是否已满

  • 如果栈顶指针等于栈的最大容量减一,说明栈已满,返回true;
  • 否则,栈未满,返回false。
function isStackFull(stack):
    if stack.top == stack.capacity - 1:
        return true
    else:
        return false

判断队列是否为空

  • 如果队列的头和尾指针相等,说明队列为空,返回true;
  • 否则,队列不为空,返回false。
function isQueueEmpty(queue):
    if queue.head == queue.tail:
        return true
    else:
        return false

判断队列是否已满

  • 如果尾指针加1对队列最大容量取模等于头指针,说明队列已满,返回true;
  • 否则,队列未满,返回false。
function isQueueFull(queue):
    if (queue.tail + 1) % queue.capacity == queue.head:
        return true
    else:
        return false

判断栈与队列的大小

获取栈的大小

  • 如果栈为空,返回0;
  • 否则,返回栈顶指针加1。
function getStackSize(stack):
    if stack.top == -1:
        return 0
    else:
        return stack.top + 1

获取队列的大小

  • 如果队列为空,返回0;
  • 否则,返回尾指针减头指针对队列最大容量取模加1。
function getQueueSize(queue):
    if queue.head == queue.tail:
        return 0
    else:
        return (queue.tail - queue.head + queue.capacity) % queue.capacity + 1

栈中数据的访问方式是什么?

栈中数据的访问方式操作描述如下:

获取栈顶元素

  • 如果栈为空,返回空值null;
  • 否则,返回栈顶元素。
function getTop(stack):
    if stack.top == -1:
        return null
    else:
        return stack.data[stack.top]

获取栈中指定位置的元素

  • 如果栈为空或指定位置超出范围,返回空值null;
  • 否则,返回指定位置的元素。
function getStackElement(stack, position):
    if stack.top == -1 or position < 0 or position > stack.top:
        return null
    else:
        return stack.data[position]

如何遍历栈中的元素

从栈底到栈顶遍历栈中元素

  • 如果栈为空,结束遍历;
  • 否则,从栈底开始遍历栈中元素直到栈顶。
function traverseStackFromBottom(stack):
    if stack.top == -1:
        return
    for i from 0 to stack.top:
        // 对每个元素执行相应操作
        process(stack.data[i])

从栈顶到栈底遍历栈中元素

  • 如果栈为空,结束遍历;
  • 否则,从栈顶开始遍历栈中元素直到栈底。
function traverseStackFromTop(stack):
    if stack.top == -1:
        return
    for i from stack.top to 0:
        // 对每个元素执行相应操作
        process(stack.data[i])

在栈的顶部添加或者删除元素

在栈的顶部添加或者删除元素操作描述如下:

在栈顶添加元素

  • 如果栈已满,操作失败,返回false;
  • 否则,将元素添加到栈顶,栈顶指针加1,操作成功,返回true。
function pushToStack(stack, element):
    if isStackFull(stack):
        return false
    stack.top = stack.top + 1
    stack.data[stack.top] = element
    return true

从栈顶删除元素

  • 如果栈为空,操作失败,返回null;
  • 否则,删除栈顶元素并返回,栈顶指针减1,操作成功。
function popFromStack(stack):
    if isStackEmpty(stack):
        return null
    element = stack.data[stack.top]
    stack.top = stack.top - 1
    return element

标签:队列,top,元素,栈顶,中栈,queue,数据结构,stack
From: https://www.cnblogs.com/yyyyfly1/p/17473088.html

相关文章

  • 利用RabbitMQ 的死信队列来做定时任务
    常用的应用场景死信队列常常用作延时关闭订单(如订单的超时后的取消订单等),虽然小项目中可以用定时轮询的方法进行检查,但是数据量一旦比较大时,定时轮询将给数据库带来不小的压力,而且定时间隔无法进行动态调整,特别是一个系统中,同时存在好几个定时器的时候,就显得非常的麻烦,同时给数据......
  • ds:队列的基本实现
     一.顺序队1.入队判断队满,出队判断队空;2.顺序队定义时,要注意front、rear是下标,不是指针。typedefstruct{intdata[maxsize];intrear,front;//front:队头元素的下标。rear:队尾元素的后一个位置的下标(下一个待插入的位置),}sqListQueue;3,如果判断队......
  • 谈谈队列(Queue)
    写在前面蒟蒻发第二篇博客了!作者依然是个新手,依然没有脑子,因此本文可能存在大量不足之处,还请多多指教。对于各种错误,欢迎批评指正!队列队列(Queue),是一种数据结构,在STL中可直接调用。具体地来说,队列是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。这也......
  • C语言:数据结构之单链表(二)
    上一篇随笔谈了谈单链表是什么东西,然后进行了初始化,这篇随笔就开始对其进行操作了,首先是增,删,改,查的增。增,顾名思义就是要增加新的元素,单链表是链式的,那就要考虑怎么去加新元素,有三种,从头部添加,从尾部添加,从中间添加。先说说从尾部添加,这个比较好理解,直接在尾部放一个结点......
  • 2023年7月7日,线程池的调用原理,线程池底层,任务队列
    线程池的调用原理线程池的七大参数:核心线程数、最大线程数、任务队列、拒绝策略、闲置时间、时间单位、线程工厂任务进入线程池后线程池的执行顺序:核心线程(用完)---处理完一个任务后会取出任务队列中的第一个任务来执行任务队列(装满)普通线程(用完)拒绝策略深入线程池ExecutorServicep......
  • 消息队列-八股文
    消息队列选型-√kafka:优点:吞吐量高,性能高缺点:功能单一,有丢失消息的风险rocketMQ:优点:功能完善,性能好缺点:客户端仅支持JavaRocketMQ事务消息实现-※RocketMQ底层实现原理-※消息队列如何保证可靠传输可靠传输:不能多不能少1.消费者实现幂等性,哪怕多收消息,......
  • 数据结构day1
    数据结构的一些基本概念:1、数据。2、数据项、3、数据元素、4、数据结构5、算法数据的逻辑结构:1、线型结构2、树型结构3、图型结构数据的存储结构:1、顺序结构2、链式结构链式表:1、带头节点的链表2、不带头节点的链表功能受限的表结构:栈:************实现一个函数判......
  • 数据结构与算法(一)
    需要点Java编程基础常见的数据结构栈(Stack):栈是一种特殊的线性表,它只能在一个表的一个固定端进行数据结点的插入和删除操作。队列(Queue):队列和栈类似,也是一种特殊的线性表。和栈不同的是,队列只允许在表的一端进行插入操作,而在另一端进行删除操作。数组(Array):数组是一种聚合数据......
  • C/C++数据结构与算法课程设计[2023-07-06]
    C/C++数据结构与算法课程设计[2023-07-06]数据结构与算法课程设计一、课程设计的目的、要求和任务 本课程设计是为了配合《数据结构与算法》课程的开设,通过设计完整的程序,使学生掌握数据结构的应用、算法的编写等基本方法。1.课程的目的(1)使学生进一步理解和掌握课堂上所学......
  • BZOJ 1915: [Usaco2010 Open]奶牛的跳格子游戏 单调队列优化dp
    1915:[Usaco2010Open]奶牛的跳格子游戏TimeLimit: 4Sec  MemoryLimit: 64MBSubmit: 281  Solved: 110[Submit][Status][Discuss]Description奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子,(3<=N<=250,000),编号为1..N......