Hello算法5:栈和队列

本文详细介绍了栈和队列这两种基本的线性数据结构,包括它们的工作原理、基于列表、数组和链表的不同实现方式,以及在浏览器导航和程序内存管理中的应用。
摘要由CSDN通过智能技术生成

本文是基于k神的Hello 算法的读书笔记,请支持实体书。
https://www.hello-algo.com/chapter_paperbook/

栈是一种遵循先入后出的逻辑的线性数据结构。就像一叠盘子一样,要去下面的盘子必须先拿起上面的盘子。

栈的实现

栈的实现可以通过列表或数组。

class ArrayStack:

    def __init__(self):
        self.__stack: list[int] = []

    def size(self):
        return len(self.__stack)

    def is_empty(self):
        if self.size():
            return True

    def push(self, val):
        """入栈"""
        self.__stack.append(val)

    def pop(self):
        """出栈"""
        if self.is_empty():
            raise IndexError("栈为空")
        return self.__stack.pop()

    def peek(self):
				"""查看栈顶元素"""
        if self.is_empty():
            raise IndexError("栈为空")
        return self.__stack[-1]

栈的应用

浏览器的前进、后退

程序的内存管理

队列

队列是一种遵循先进先出的逻辑的线性数据结构,模拟了排队现象。

队列常用操作

import collections

que = collections.deque()

# 入队
que.append(1)
que.append(2)
que.append(3)

# 访问队首元素
front = que[0]

# 出队
pop = que.popleft()

基于链表的实现

class NodeListQueue:

    def __init__(self):
        self.__front: ListNode | None = None  # 首节点
        self.__rear: ListNode | None = None  # 尾节点
        self.__size = 0

    def size(self):
        return self.__size

    def is_empty(self):
        return self.__size == 0

    def push(self, num):
        """入队操作"""
        node = ListNode(num)
        # 如果队列为空,就将头节点和尾节点都指向它
        if self.is_empty():
            self.__front = node
            self.__rear = node
        # 如果不为空,将尾节点的下一个节点,指定为它
        else:
            self.__rear.next = node
            self.__rear = node
            self.__size += 1

    def peek(self):
        """访问队首元素"""
        if self.__front:
            return self.__front.val
        else:
            print("队列为空")
            return False

    def pop(self):
        num = self.peek()
        self.__front = self.__front.next
        self.__size -= 1
        return num

基于数组的实现

其中精妙的点在于,用取余操作,实现了越过队尾的时候回到队首

class ArrayQueue:
    """基于环形数组实现的队列"""

    def __init__(self, size: int):
        """构造方法"""
        self.__nums: list[int] = [0] * size  # 用于存储队列元素的数组
        self.__front: int = 0  # 队首指针,指向队首元素
        self.__size: int = 0  # 队列长度

    def capacity(self) -> int:
        """获取队列的容量"""
        return len(self.__nums)

    def size(self) -> int:
        """获取队列的长度"""
        return self.__size

    def is_empty(self) -> bool:
        """判断队列是否为空"""
        return self.__size == 0

    def push(self, num: int):
        """入队"""
        if self.__size == self.capacity():
            raise IndexError("队列已满")
        # 计算尾指针,指向队尾索引 + 1
        # 通过取余操作,实现 rear 越过数组尾部后回到头部
        rear: int = (self.__front + self.__size) % self.capacity()
        # 将 num 添加至队尾
        self.__nums[rear] = num
        self.__size += 1

    def pop(self) -> int:
        """出队"""
        num: int = self.peek()
        # 队首指针向后移动一位,若越过尾部则返回到数组头部
        self.__front = (self.__front + 1) % self.capacity()
        self.__size -= 1
        return num

    def peek(self) -> int:
        """访问队首元素"""
        if self.is_empty():
            raise IndexError("队列为空")
        return self.__nums[self.__front]

队列的应用

  • 待办事项
  • 淘宝订单
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值