数据结构-队列

队列

  • 一.定义
  • 二.特点
  • 三.时间复杂度
  • 四.基本运算
    • 队列的顺序存储
    • 队列的链式存储
  • 五.循环队列和链式队列的比较

一.定义

队列(queue)是一种先进先出线性表,简称FIFO。在表一端(表尾)插入,在另一端(表头)删除。

二.特点

1)在表一端(表尾)插入,在另一端(表头)删除的线性表。
2)表的插入操作称为入队,表的取出操作称为出队。
3)队列的存储结构分为顺序存储或链式存储,顺序存储称为顺序队,链式存储称为链队。以循环顺序队列更常见。
4)队列分为两种:双向队列和单向队列 。
单向队列(队列):只能在一端删除数据,另一端插入数据。
双向队列(双端队列):两端都可以进行插入数据和删除数据操作。

三.时间复杂度

四.基本运算

  • Queue()创建一个空的队列

  • enqueue(item)往队列中添加一个item元素

  • dequeue()从队列头部删除一个元素

  • is_empty()判断一个队列是否为空

  • size()返回队列的大小

队列的顺序存储

利用数组实现队列的顺序存储
1.例:a1,a2依次出队数据结构-队列_第1张图片
入队操作时间复杂度为O(1):每当一个元素入队时,rear会加一。
出队操作时间复杂度为O(n):每次当一个元素出队时,后面的元素会依次向前移。
2.如何改进出队的时间性能?
数据结构-队列_第2张图片
数据结构-队列_第3张图片
front与rear初始值为-1.
入队:当有数据入队的时候,rear值加一(移到下一个单元),数据放在rear所指向的位置。
出队:当有数据出队的时候,front加一(移到下一个单元),再将front位置上的数据移除。
此时,入队与出队的时间复杂度为O(1)
3.继续入队会出现什么情况?
数据结构-队列_第4张图片
后面没办法入队,但是前面还有空闲
4.如何解决假溢出?
数据结构-队列_第5张图片
解决假溢出的办法就是后面满了,我们就再从头开始,也就是首尾相接的循环。我们把队列的这种头尾相接的顺序存储结构称为循环队列
数据结构-队列_第6张图片
a6入队应该放在0的那个位置,因此我们可以求余的方法求rear值。
5.循环队列的基本操作:
数据结构-队列_第7张图片
maxsize是一个常量,定义队列的最大长度。
python代码:

class SqQueue(object):
    def __init__(self, maxsize):
        self.queue = [None] * maxsize
        self.maxsize = maxsize
        self.front = -1
        self.rear = -1

    # 返回当前队列的长度
    def QueueLength(self):
        return (self.rear - self.front + self.maxsize) % self.maxsize
    """判断队满"""
    def isFull(self):
         return (self.rear + 1) % self.maxsize == self.front
    """判断队空"""
    def isEmpty(self):
        return self.rear == self.front
    '''入队'''
    # 如果队列未满,则在队尾插入元素,时间复杂度O(1)
    def EnQueue(self, data):
        if self.isFull():
            print("The queue is full!")
        else:
            self.rear = (self.rear + 1) % self.maxsize
            self.queue[self.rear] = data
           # self.queue.insert(self.rear,data)
            
    """出队"""
    # 如果队列不为空,则删除队头的元素,时间复杂度O(1)
    def DeQueue(self):
        if self.rear == self.front:
            print("The queue is empty!")
        else:
            self.front = (self.front + 1) % self.maxsize
            data = self.queue[self.front]
            self.queue[self.front] = None
            return data

    # 输出队列中的元素
    def ShowQueue(self):
        for i in range(self.maxsize):
            print(self.queue[i],end=',')
        print(' ')

队列的链式存储

又称链式队列
1.入队:在队尾添加元素
front头指针不动,随着元素的增加,尾指rear依次加一,并放在最后一个元素上
主要变化:
创建新结点Queuenode
rear-next=Queuenode
rear = tQueueNode
数据结构-队列_第8张图片
2.出队:队头删除元素
rear尾指针不动,随着元素的删除,头指front依次加一,并放在头一个元素上
伪代码:
p=front-next
front-next=p-next
delete p
数据结构-队列_第9张图片
python代码

class QueueNode():
    def __init__(self):
        self.data = None
        self.next = None
class LinkQueue():
    def __init__(self):
        tQueueNode = QueueNode()
        self.front = tQueueNode
        self.rear = tQueueNode
    '''判断是否为空'''
    def IsEmptyQueue(self):
        if self.front == self.rear:
            iQueue = True
        else:
            iQueue = False
        return iQueue
    '''进队列'''
    def EnQueue(self,da):
        tQueueNode = QueueNode()
        tQueueNode.data = da
        self.rear.next = tQueueNode
        self.rear = tQueueNode
        print("当前进队的元素为:",da)
    '''出队列'''
    def DeQueue(self):
        if self.IsEmptyQueue():
            print("队列为空")
            return
        else:
            tQueueNode = self.front.next
            self.front.next = tQueueNode.next
            if self.rear == tQueueNode:
                self.rear = self.front
            return tQueueNode.data
    def  GetHead(self):
        if self.IsEmptyQueue():
            print("队列为空")
            return
        else:
            return self.front.next.data
    def CreateQueueByInput(self):
        data = input("请输入元素(回车键确定,#结束)")
        while data != "#":
            self.EnQueue(data)
            data = input("请输入元素(回车键确定,#结束)")
    '''遍历顺序队列内的所有元素'''
    def QueueTraverse(self):
        if self.IsEmptyQueue():
            print("队列为空")
            return
        else:
            while self.front != self.rear:
                result = self.DeQueue()
                print(result,end = ' ')

五.循环队列和链式队列的比较

时间复杂度
循环队列和链式队列的基本操作都需要常数时间O(1)
空间复杂度
循环队列:必须预先确定一个固定的长度,所以有存储元素个数的限制和空间浪费的问题

链式队列:没有队列满的问题,只有当内存没有可用空间时才会出现队列满,但是每一个元素都需要一个指针域,从而产生了结构性开销。

参考资料:数据结构与算法
https://blog.csdn.net/u012626619/article/details/80658397

你可能感兴趣的:(数据结构与算法,#,数据结构,数据结构,python,队列)