Stack 与 Queue互相转换

本文探讨了数据结构中栈和队列的特性,并详细解释了如何通过两次使用栈实现队列的功能,以及如何利用两个队列实现栈的后进先出特性。这不仅加深了对这两种基本数据结构的理解,还提供了实际的转换方法。

Stack、Queue

  栈:后进先出,只可插入或取出栈顶元素
  队列:先进先出,只可取出队首元素,插入队尾元素

  栈和队列的实现很相似,两种数据结构是否可以互相转换?
    答案是肯定的,栈与队列相互转换可以加深栈与队列的理解

Stack->Queue

  用栈实现队列—>用后进先出实现先进先出

  方案:利用两次后进先出(栈)即可实现先进先出(队列)
    比较简单,直接看图应该就可以看懂如何实现,如图:

Stack->Queue

Queue->Stack

  用队列实现栈—>用先进先出实现后进先出

  方案:利用两次先进先出(队列)实现后进先出(栈)
    1 需要两个队列,两个队列指针,初始:队列指针(out)指向队列1,队列指针(in)指向队列2
    2 首先数据元素全部进入队列out
    3 需要弹出一个元素,队列out中N-1个数据进入队列in,将队列out的元素出队
    4 in 与 out 交换指向队列
    需要弹出元素 重复 2-4步骤
    如图:

Queue->Stack
### 队列、和堆的概念 #### 队列 (Queue) 队列是一种线性数据结构,遵循先进先出(FIFO, First In First Out)的原则。这意味着最早进入队列的元素会最先被移除。这种特性使得队列非常适合用于任务调度和消息传递等场景[^2]。 ```java // Java 实现队列的一个简单例子 class Queue { private int[] elements; private int size; public Queue(int capacity) { this.elements = new int[capacity]; this.size = 0; } // 添加元素到队尾 public void enqueue(int element) { if (size >= elements.length) throw new RuntimeException("Queue is full"); elements[size++] = element; } // 移除并返回队首元素 public int dequeue() { if (isEmpty()) throw new RuntimeException("Queue is empty"); int frontElement = elements[0]; // 将剩余元素向前移动一位覆盖掉已删除的位置 for (int i = 0; i < size - 1; ++i) elements[i] = elements[i + 1]; --size; return frontElement; } } ``` #### (Stack) 也是一种线性数据结构,不过它遵循的是后进先出(LIFO, Last In First Out)原则。即最后加入顶的元素会被优先处理。这有助于解决诸如表达式求值等问题[^1]。 ```java // 使用数组实现的例子 public class Stack { private final int maxSize; private final int[] stackArray; private int topOfStack; public Stack(int size) { maxSize = size; stackArray = new int[maxSize]; topOfStack = -1; } // 向中压入一个整数值 public boolean push(int value) { if (!isFull()) { stackArray[++topOfStack] = value; return true; } else { System.out.println("Could not insert data because the stack is full."); return false; } } // 从弹出最上面的数据项 public Integer pop() { if (!isEmpty()) return stackArray[topOfStack--]; else return null; } } ``` #### 堆 (Heap) 不同于上述两种基本的数据结构,堆是一棵完全二叉树,分为最大堆和最小堆两种形式。对于最大堆而言,父节点总是大于等于其子节点;而对于最小堆,则相反。堆常用来构建高效的优先级队列以及执行快速的选择操作,比如找到一组数中的前k大或小的元素[^5]。 ```python import heapq # Python 中利用heapq模块来创建一个小根堆 nums = [3, 1, 4, 1, 5, 9, 2, 6] # 把列表转换成堆 heapq.heapify(nums) print(heapq.heappop(nums)) # 输出最小值 while nums: print(heapq.heappop(nums), end=' ') # 继续输出后续最小值直到为空 ``` ### 操作差异 - **插入**: 对于`队列`来说是在末端添加新成员(`enqueue`);而在``里则是向顶部放置新的项目(`push`);至于`堆`, 插入过程涉及维护特定性质(如保持最大/最小),可能需要调整位置。 - **删除**: `队列`从前端取出(`dequeue`);``则从顶端取走(`pop`);`堆`同样需考虑维持内部秩序,一般情况下是从根部拿走最高优先级者,并重新排列其余部分以恢复原有属性。 - **查找**: 这三种结构都不支持随机访问模式下的高效查询功能。如果想要定位某个具体目标的话,往往不得不遍历整个集合直至发现为止。 ### 关联之处 尽管三者的运作机制存在显著差别,但在某些应用场合下可以互相替代或是组合运用。例如,在设计复杂度较低的任务管理系统时,既可以采用单个大型全局队列也可以通过多个局部化的临时来进行短期存储管理。另外值得注意的一点是,当涉及到动态内存分配的时候,“堆区”指的是程序运行期间可自由支配的空间区域,而非这里讨论的那种逻辑上的抽象数据类型——虽然名称相同但实际意义完全不同[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值