4、两个栈实现一个队列

本文介绍如何利用两个栈实现一个队列的数据结构,并提供具体的代码实现。通过这种方式,我们可以灵活地在队列中添加元素和删除元素,同时保持队列的先进先出特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两个栈实现一个队列

  • 请用两个栈,实现一个队列
  • 功能 add delete length

队列

  • 先进先出
  • API : add delete length

逻辑结构 VS 物理结构

  • 队列是逻辑结构,抽象模型
  • 简单的,可以使用数组、链表实现
  • 复杂的队列服务,需单独设计

思路

  • 入队直接使用push填入栈1
  • 出队:先将栈1的元素pop到栈2,然后栈2使用pop,最后栈2在pop到栈1

示例:入队===> ABCD === 【DCBA】

——
D
C
B
A
——

此时A在栈底,但是队列是先进先出,要删除A,需要将A放到栈顶。

出队:1、栈1【DCBA】=pop=>栈2【ABCD】

——
A
B
C
D
——

此时栈2中,A是在栈顶,可以删除A,满足队列先进先出的规则。

2、栈2【ABCD】=pop(A)=> 【BCD】

——
B
C
D
——

此时已经删除完了A,但是后续继续增加新的元素E或F,应该在D的后面,

3、栈2【BCD】=pop=> 栈1【DCB】

——
D
C
B
——

所以第三步D在栈顶,新增新的元素E或F,就在D的后面,满足的队列的先进先出规则。

代码实现

class MyQueue {
  private stack1: number[] = []
  private stack2:number[] = []

  add(num:number) {
    this.stack1.push(num)
  }

  delete():number | null {
    let res;
    const stack1 = this.stack1
    const stack2 = this.stack2
	// 将stck1 所有元素移动到stack2中
    while(stack1.length){
      const n:number = stack1.pop() as number
      if (n != null){
        stack2.push(n)
      }
      
    }
	// stack2 pop
    res = stack2.pop()

    // 将 stack2 所有元素“还给”stack1
    while(stack2.length){
      const n = stack2.pop() as number
      if (n != null) {
        stack1.push(n)
      }
      
    }

    return res || null

  }

  get length():number {
    return this.stack1.length
  }
}

功能测试

const q = new MyQueue()

q.add(100)
q.add(200)
q.add(300)
console.log(q.length) // 3
console.log(q.delete()) // 100
console.log(q.length) // 2

满足队列先进先出的规则

单元测试

describe('两个栈,一个队列',() => {
    it('add and length', () => {
        const q = new MyQueue()
        q.add(100)
        q.add(200)
        q.add(300)
        expect(q.length).toBe(3)
    })
    
    it('delete', () => {
        const q = new MyQueue()
        expect(q.delete()).toBeNull()
        q.add(100)
        q.add(200)
        q.add(300)
        expect(q.length).toBe(3)
        expect(q.delete()).toBe(100)
        expect(q.length).toBe(2)
        expect(q.delete()).toBe(200)
        expect(q.length).toBe(1)
        expect(q.delete()).toBe(300)
        expect(q.length).toBe(0)
    })
})

性能分析

  • 时间复杂度:add==>O(1); delete ==> O(n)
  • 空间复杂度,整体是O(n)

虽然在delete中有两次循环,但不是嵌套关系,所以它是时间和空间复杂度都是O(n);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天界程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值