Python-数据结构与算法(三、队列)

保证一周更两篇吧,以此来督促自己好好的学习!代码的很多地方我都给予了详细的解释,帮助理解。好了,干就完了~加油!
声明:本python数据结构与算法是imooc上liuyubobobo老师java数据结构的python改写,并添加了一些自己的理解和新的东西,liuyubobobo老师真的是一位很棒的老师!超级喜欢他~
如有错误,还请小伙伴们不吝指出,一起学习~
No fears, No distractions.
小伙伴们中秋节快乐~

一、什么是队列

队列(Queue),顾名思义,有排队的意思,想象你要去学校食堂打饭,而打饭有着先来后到的原则,因此就需要排队,先到的人先吃-,后到的人后吃- -。这就是一个队列呀。

  1. 队列也是一种线性结构
  2. 相比数组,队列的所有操作也是数组的子集,只能从一端(队尾)添加元素,从另一端(队首)取出元素。
  3. 队列是一种先进先出的数据结构(先到先得)即First In First Out
  4. 队列相关操作:
    enqueue-------入队操作
    dequeue-------出队操作
    getFront------看一下队首的元素是谁(对于队列,和栈是相似的,我们只对队首的元素感兴趣)
    getSize-------得到队列中有效元素的个数
    isEmpty-------判断队列是否为空
    从用户的角度看,支持这些操作就好。具体底层实现,用户不关心。实际底层有多种实现方式。比如基于前面的数组实现,或者自己从底层再写一个队列来实现。本文基于前面所实现的数组来实现一个队列,能够自动动态扩容。当然从底层实现队列也是非常简单的,因为涉及到的操作都是我们实现的Arr类的子集。

二、实现

# -*- coding: utf-8 -*-
# Author:           Annihilation7
# Data:             2018-09-24
# Python version:   3.6

import Array

class Queue:
    def __init__(self, capacity=10):
        """
        构造函数
        :param capacity: 初始容量,默认值为10
        """
        self.array = Array.Arr(capacity)    # 底层由我们在第一章完成的Arr类来实现,毕竟Queue的操作只是Arr类的部分操作

    def getSize(self):
        """
        得到队列内有效元素的个数
        时间复杂度:O(1)
        :return: 有效元素的个数
        """
        return self.array.getSize()     # 复用Arr类的getSize方法,Arr类中已经对它的_size进行类很好的维护操作

    def getCapacity(self):
        """
        因为是由我们自己实现的数组作为底层数据结构,因此能够查看当前队列的容量大小,实际上这个函数用户并用不到
        时间复杂度:O(1)
        :return: 队列的容量
        """
        return self.array.getCapacity() # 复用Arr类的getCapacity方法

    def isEmpty(self):
        """
        判断队列是否为空
        时间复杂度:O(1)
        :return: bool值,空为True
        """
        return self.array.isEmpty()     # 复用Arr类的isEmpty()方法

    def enqueue(self, elem):
        """
        入队操作,注意本文中数组右侧为队尾,左侧(索引为0的地方)为队首
        时间复杂度:O(1)
        :param elem: 将要入队的元素
        """
        self.array.addLast(elem)        # 复用Arr类的addLast操作,进行入队

    def dequeue(self):
        """
        出队操作,数组左边出队,就是在索引为0的地方出队。
        时间复杂度:O(n)
        :return: 出队的元素的值
        """
        return self.array.removeFirst()

    def getFront(self):
        """
        拿到对首的元素,因为往往队首的元素是我们关心的元素。
        时间复杂度:O(1)
        :return: 队首元素
        """
        return self.array.getFirst()    # 复用Arr类的getFirst操作,也不用进行判空神马的类,因为Arr类中的函数都帮我们干了

    def printQueue(self):
        """打印队列的操作"""
        print('Queue: Front--- ', end='')           # 左边是队首
        for i in range(self.getSize()):
            if i != self.getSize() - 1:             # 强迫症。。为了打印美观- -
                print(self.array[i], end='  ')      # 别忘了我们的Arr是支持索引操作的哦
            else:
                print(self.array[i], end='')
        print(' ---Tail')                           # 右边是队尾哦
        print('Size: %d' % (self.getSize()))      # 有效元素个数的打印

三、测试

import queue			# 我们的Queue类写在这个py文件中了
import numpy as np

np.random.seed(7)
test = queue.Queue()
print(test.getSize())
print(test.getCapacity())
print(test.isEmpty())
for i in range(17):
    test.enqueue(np.random.randint(10))
test.printQueue()
for i in range(7):
    test.dequeue()  # 不需要dequeue的返回值了
test.printQueue()
print(test.getFront())

四、输出

0
10
True
Queue: Front--- 4  9  6  3  3  7  7  9  7  8  9  8  7  6  4  0  7 ---Tail
Size: 17
Queue: Front--- 9  7  8  9  8  7  6  4  0  7 ---Tail
Size: 10
9

五、一个小问题

既然队列的出队操作是O(n)的时间复杂度,那么有没有什么办法让入队和出队都变成O(1)的时间复杂度呢?答案就在我下一节要讲的循环队列中!干就完了,下章见!

若有还可以改进、优化的地方,还请小伙伴们批评指正!

猜你喜欢

转载自blog.csdn.net/Annihilation7/article/details/82807276