队列的python实现

队列的python实现

定义

  • 队列是一种基本的数据结构,与“栈”互为表亲关系,队列是由一系列对象组成的集合,这些元素的插入和删除遵循先入先出的原则,即元素可以任意时刻进入队列,但只有处在队列最前面的元素才能被删除。

队列的抽象数据类型

  • 通常来说,队列的抽象数据类型定义了一系列对象组成的集合,其中元素的访问和删除被限制在队列的第一个元素,而元素的插入被限制在队列的尾部。
  • 队列Q的抽象数据类型支持以下基本方法:
    • Q.enqueue() : 支持在队列的尾部增加一个元素
    • Q.dequeue() : 删除并返回队列的第一个元素,如果队列为空,则触发错误。
    • Q.first() : 在不删除第一个元素的情况下返回队列的第一个元素,如果队列为空,则触发错误。
    • Q.is_empty() : 判断队列是否为空队列,并返回结果。
    • len(Q) : 返回队列的长度,即队列元素的个数。

基于数组的队列的实现

  • 用python实现队列,最简单的做法是使用列表类修改一个适配器类,添加元素时在列表的末端加入,删除元素时通过pop(0)来删除队列的第一个元素。但是这样操作的效率很低,pop操作会对序列产生“洞”,pop()操作的调用总是处于最坏情况。
  • 最佳的实现方式是通过循环使用数组。让队列的前端更趋向于列表的右端,而队列内的元素在底层数组的尾部“循环”。此时底层数组假定的长度N是大于队列中实际元素的个数。
  • 取模操作是处理循环数组的理想操作。

python队列的实现方法

  • """
    本文代码用于以python实现队列结构
    """
    
    
    class Error(Exception):
        """
        自定义异常类的原因是避免空栈调用top()/pop()方法报错时的提示信息是列表类的异常信息
        """
        pass
    
    
    class Arrayqueue(object):
        DEFAULT_SIZE = 10
    
        def __init__(self):
            """
            _front表示队列第一个元素的索引;
            _size表示队列内元素的数目;
            _data是一个固定容量的列表实例
            """
            self._front = 0
            self._size = 0
            self._data = [None] * Arrayqueue.DEFAULT_SIZE
    
        def __len__(self):
            return self._size
    
        def is_empty(self):
            return self._size == 0
    
        def is_full(self):
            return self._size == len(self._data)
    
        def first(self):
            return self._data[self._front]
    
        def enqueue(self, arg):
            if self.is_full():
                raise Error("arrayqueue is full")
            end = (self._front + self._size) % len(self._data)
            self._data.insert(end, arg)
            self._size += 1
    
        def dequeue(self):
            if self.is_empty():
                raise Error("arrayqueue is empty")
            first_index = self._front
            # 此处取模操作是为了第一位元素处于数组末端的情况
            self._front = (self._front + 1) % len(self._data)
            self._data[first_index] = None
            self._size -= 1
    
    
    if __name__ == "__main__":
        Q = Arrayqueue()
        Q.enqueue(1)
        Q.enqueue(2)
        print(len(Q))
        print(Q.first())
        Q.dequeue()
        print(Q.first())
    
    

    注:第51行设为None的原因与python的回收未使用空间的机制有关,在内部python对已存的对象维护了一个对其的引用计数的计数器,如果计数器变为0,这个对象就无法访问,系统会回收这部分内存。对于离开队列的元素,队列已经不再负责它的存储,所以需要减少这个元素的引用计数。

基于单链表的队列的实现

  • 由于需要对队列的两端进行操作,我们显式地为队列类Q维护两个实例变量_head_tail,队列的首元素和尾元素对映的是链表的头节点和尾节点。

  • # !/usr/bin/env python
    # -*-coding:utf-8 -*-
    
    """
    # File       : link_queue_of_python.py
    # Time       :2022/1/10 15:10
    # Author     :kkk
    # version    :python 3.6
    # Description:本文件用于解释如何通过单链表实现队列
    """
    
    
    class Error(Exception):
        pass
    
    
    class LinkQueue(object):
        class Node(object):
            """
            定义节点类
            element实例表示的是初始化的节点与它应当存在的下一节点之间的映射关系,在单链表表示队列的情况下,
            由于新增的队列元素必然是增加在队列的尾端,即单链表的尾节点,那么element是固定为None的
            """
            def __init__(self, element, value):
                self.element = element
                self.value = value
    
        def __init__(self):
            """
            初始化三个实例,以此表示头节点、尾节点、队列元素个数
            """
            self._head = None
            self._tail = None
            self._size = 0
    
        def is_empty(self):
            return self._size == 0
    
        def first(self):
            if self.is_empty():
                raise Error("the queue is empty")
    
            return self._head.value
    
        def pop(self):
            if self.is_empty():
                raise Error("the queue is empty")
            value = self._head.value
            self._head = None
            return value
    
        def enqueue(self, value):
            new_node = self.Node(None, value)
            if self.is_empty():
                self._head = new_node
            else:
                self._tail.element = new_node
            self._tail = new_node
            self._size += 1
    
        def dequeue(self):
            if self.is_empty():
                raise Error("the queue is empty")
            value = self._head.value
            if self._size == 1:
                self._head = None
                self._tail = None
            else:
                new_element = self._head.element
                self._head = new_element
            self._size -= 1
            return value
    
        def __len__(self):
            return self._size
    
    if __name__ == "__main__":
        Q = LinkQueue()
        Q.enqueue(1)
        Q.enqueue(2)
        print(len(Q))
        print(Q.first())
        Q.dequeue()
        print(Q.first())
    
  • 在性能方面,基于单链表实现的队列,所有操作在最坏情况下运行的时间为常数,而空间使用率和当前队列的元素个数呈现线性关系。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值