队列python(数据结构与算法)--基础图解

队列的概念

队列是由一系列对象组成的集合,这些对象的插入和操作和删除遵循先进先出(First  in First out ,FIFO),也就是说只有处于队列最前面的元素才能被删除;

常见概念:

  1. 队尾:将队列中允许插入的一端称为队尾,一般指向当前的元素所在的位置
  2. 对首:将队列中允许删除的一端称为对首,队尾一般指向下一个数据储存的位置;

队列数据结构图解:

因为入队和出队操作分别再队尾和队首进行,所以增加front来指示队首的元素的位置,rear来指示队尾元素的下一个存储单元的位置。

按照实现方法(基于那个数据结构)队列分类:

  1. 顺序队列,即基于数组实现
  2. 链表队列,即基于链表实现

循环队列

上述队列,顺序队列和链表队列中,如果不断重复地往队列中添加元素,然后删除队首的元素,随着时间的推移,就会发生这样的事,底层的大小将逐渐增长到O(m),(假设底层的数组是无限大的),如下图所示。其中m是等于自队列创建以来进行追加元素操作的数量总和,而不是当前队列中元素的数量,故系统可能让这些元素存储在一个任意大小的列表中,为了使队列更加健壮,实现循环队列来解决这种问题,

循环队列原理:

让队列的前端趋于右端,并且让队列内的元素在底层数组的尾部“循环”,即假定底层数组的长度为固定值N,它比实际队列的中的元素的数量大。

如下图所示,在经过一系列的插入元素,删除元素后,在队列尾部重新插入元素时,如果超过底层数组的大小,会将数据插入到底层数组的头部;

实现:

主要用到取模操作来实现队列的队尾和队首索引位置的更新,F= (f+1)%N,N为数组的大小,f为当前索引,F为更新后的索引。

例如:

顺序队列

# -*- coding: utf-8 -*-
"""
Created on Thu Dec 19 09:53:44 2019

@author: dell
"""


#队列的抽象数据描述:先进先出
#队列的删除只能在表的尾部进行
#删除操作只能在表头进行
#在队列中允许进行插入的一端称为队尾,
#允许删除的操作的一端称为队首
#队列的插入操作叫入队
#队列的删除操作叫做出队

    
"""顺序对列""" 
#对列的操作在对首和队尾进行,所以增加变量front来指示对首的位置,rear指示队尾元素的下一个‘
#储存单元的位置

"""顺序对列""" 
#对列的操作在对首和队尾进行,所以增加变量front来指示对首的位置,rear指示队尾元素的下一个‘
#储存单元的位置

class SqQueue():

    
    def __init__(self,maxsize):
        
        self.maxsize = maxsize
        self.quequeElem = [None] * self.maxsize
        self.front = 0 #指向对首的元素
        self.rear = 0 #指向队尾元素的下一个存储单元    

    def clear(self):
        self.front = 0
        self.rear = 0

    def isEmpty(self):
        return self.front == self.rear

    def length(self):
        return self.rear - self.front

    def peek(self):
        #返回对首元素
        if self.isEmpty():
            return None
        else:
            return self.quequeElem[self.front]

    def offer(self,x):
        #将数据元素x插入对列成为队尾的元素
        if self.rear == self.maxsize:
            raise Exception("对列已满")
        else:
            self.quequeElem[self.rear] = x
        self.rear += 1

    def poll(self):
        #将对首的元素删除,并返回其值
        if self.isEmpty():
            return None
        p = self.quequeElem[self.front]
        self.front += 1
        return p

    def display(self):
        for i in range(self.front,self.rear):
            print(self.quequeElem[i],end=' ')
            
            
squeue = SqQueue(5)#设置队列的大小为5
squeue.offer(5)
squeue.offer(7)
squeue.offer(8)
print("队列的元素:")
squeue.display()
print("打印队首元素")#队首元素应该为5,先进先出
squeue.peek()#
print("队列的元素:")
squeue.display()
队列的元素:
5 7 8 

print("打印队首元素")
squeue.peek()
打印队首元素
Out[36]: 5

链表队列--有点问题

"""
链表对列
"""
class Node(object):
    def __init__(self,data=None,next=None):
        self.data = data#数据保存位置
        self.next = next#指向下一个数据位置

class LinkQueue():
    
    def __init__(self):
        self.front = None
        self.rear = None
        
    def clear(self):
        self.front = 0
        self.rear = 0

    def isEmpty(self):
        return self.front is None
    
    def length(self):
        p = self.front
        i = 0
        while p is not None:
            p = p.next
            i += 1
        return i

    def peek(self):
        if self.isEmpty():
            return None
        else:
            return self.front.data
        
    def offer(self,x):
        #将数据元素x插入对列成为队尾的元素
        s = Node(x)#创建新的节点
        if not self.isEmpty():
            self.rear.data = s
        else:
            self.front = s 
        self.rear = s
        
    def poll(self):
         #将对首的元素删除,并返回其值
        if self.isEmpty():
            return None
        p = self.front 
        self.front = self.front.next
        if p == self.rear:
            self.rear = None
        
    
    def display(self):
        #打印队列的数据
        p = self.front
        while p is not None:
            print(p.data,end='')

            p = p.next
            

squ = LinkQueue()
#添加元素
squ.offer(5)           
squ.offer(7)  
squ.offer(8) 
print("队列的元素:")
squ.display()
print("打印队首元素")#队首元素应该为5,先进先出
squ.peek()#

循环队列 

"""
循环对列:
对列最多放的元素:maxsize -1 
队空的条件:
front = rear
对满的条件:
front = (rear + 1) % maxsize
"""
class CircleQueue():
    def __init__(self,maxsize):
        self.maxsize = maxsize
        self.quequeElem = [None] * self.maxsize
        self.front = 0
        self.rear = 0

    def clear(self):
        self.front = 0
        self.rear = 0

    def isEmpty(self):
        return self.front == self.rear

    def length(self):
        return (self.rear - self.front +self.maxsize) % self.maxsize

    def peek(self):
        if self.isEmpty():
            raise Exception("对列是空的")
        else:
            return self.quequeElem[self.front]

    def offer(self,x):
        if (self.rear + 1) % self.maxsize == self.front:
            raise Exception("对列已满")
        self.quequeElem[self.rear] = x
        self.rear = (self.rear + 1) % self.maxsize
    
    def poll(self):
        if self.isEmpty():
            return None
        p = self.quequeElem[self.front]
        self.front = (self.front + 1) % self.maxsize
        return p
    
    def display(self):
        i = self.front
        while i != self.rear:
            print(self.quequeElem[i],end=' ')
            i = (i + 1) % self.maxsize
            
circleQueue = CircleQueue(5)#设置队列的大小为5
circleQueue.offer(8)
circleQueue.offer(7)
circleQueue.offer(6)
circleQueue.offer(5)

circleQueue.poll()
circleQueue.display()
circleQueue = CircleQueue(5)

circleQueue.offer(8)

circleQueue.offer(7)
circleQueue.offer(6)
circleQueue.offer(5)

circleQueue.poll()
Out[13]: 8

circleQueue.display()
7 6 5 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值