循环队列维持队列容量的恒定

队列的进入是从队尾进入,出去是从对头出去,但从对头出去了,若这个队列的容量是恒定的,那么他又该如何进入呢
还是从队尾进入,但这时候队尾指针就回到了数组的首位,当有元素入队时将其放入数组的首位,队尾指针继续向后移。
队列已经慢的条件:
(队尾下标+1)%数组长度 = 对头下标
上面的意思就是正常来说对头索引就是0,若是循环队列,则对头位置为队尾索引+1
这里的缘由是取模运算中后者比前者大,模就是前者,整除的话就为0
取模运算的概念:
'''
a=b//c
d = b-c*a等价于d = b%c
取模运算在负数进行除法运算时不同;向负无穷方向舍入(floor()函数)
求模运算和求余运算在第一步不同,取余运算在取c的值时,
向0 方向舍入(fix()函数);而取模运算在计算c的值时,向负无穷方向舍入(floor()函数)。
在负数除法运算中,取余运算得到的值较大,而取模运算得到的值较小;例如-2.7
取余:-2.0;取模:-3.0;而对于正数两者相同
'''

class MyQueue:
    def __init__(self, capacity):
        '''
        self.front表示对头
        self.rear表示队尾
        要明白为什么变量+1在做取模运算
        (队尾下标+1)%数组长度 = 对头下标,代表此队列满了
        队尾指针指出的位置永远空出1位,所以队列最大容量比数组长度小1
        '''
        self.list = [None] * capacity # capacity容量; 容积;
        self.front = 0
        self.rear = 0
    # 循环队列
    def enqueue(self, element):# 入队
        if (self.rear+1) % len(self.list) == self.front: # (队尾下标+1)%数组长度 = 对头下标
            # 上面的意思就是正常来说对头索引就是0,若是循环队列,则对头位置为队尾索引+1
            # 这里的缘由是取模运算中后者比前者大,模就是前者,整除的话就为0
            raise Exception("队列已满 !")
        self.list[self.rear] = element #从队尾入队
        self.rear = (self.rear+1) % len(self.list) # 取模运算

    def dequeue(self): # 出队
        if self.rear == self.front:
            raise Exception("队列为空 !")
        dequeue_element = self.list[self.front] #对头元素出队
        self.front = (self.front+1) % len(self.list) # # 取模运算
        return dequeue_element

    def output(self):
        i = self.front # i初始为对头
        while i != self.rear:
            print(self.list[i]) # 循环队列是从列表中读取数据
            # i一定会等于队尾,i的数值自增不可能比数列长度长
            i = (i+1) % len(self.list) # i随着队列的长度做取模运算

# 这是原先已经有队列了
myQueue = MyQueue(6)
myQueue.enqueue(3)
myQueue.enqueue(5)
myQueue.enqueue(6)
myQueue.dequeue()
myQueue.dequeue()
myQueue.enqueue(2)
myQueue.enqueue(4)
myQueue.output()

posted @ 2021-09-23 20:32  索匣  阅读(138)  评论(0编辑  收藏  举报