循环队列,关于队列尾的位置和浪费的一个位置

来源:3-7 循环队列的实现

Aioria_

2019-09-13

波波老师,你好!

在循环队列这部分,课程中讲到:tail为当前数组中最后一个元素的下一个位置,并且浪费一个位置。

我个人感觉可以用tail指向最后一个元素,并且不需要浪费一个空间,但是需要对队列为空的情况特殊处理,否则 front、tail都为0时会出现错误。

我个人觉得这种思路也是可行的,不需要考虑浪费一个空间的情况。我的具体实现如下,用了两种场景(触发循环和不触发循环)来简单测试,结果与波波老师的实现结果是一致的。

波波老师帮忙点评一下,这样的思路是否存在问题呢?

class LoopQueue:
    def __init__(self, capacity=10):
        self._data = [None] * capacity
        self._front, self._tail = None, None
        self._size = 0

    def __str__(self):
        data = []
        if self._front is not None and self._tail is not None:
            data = self._data[self._front:self._tail + 1] if self._tail >= self._front else self._data[self._front:] + self._data[:self._tail + 1]
        return str('<LoopQueue> capacity: {}, size: {}, data: front {} tail'.format(self.get_capacity(), self.get_size(), data))

    def enqueue(self, e):
        if self._front is None and self._tail is None:
            self._front = 0
            self._tail = 0
        else:
            if self._size == self.get_capacity():
                self._resize(self.get_capacity() * 2)
            self._tail = (self._tail + 1) % len(self._data)
        self._data[self._tail] = e
        self._size += 1

    def dequeue(self):
        if self.is_empty():
            raise ValueError('Queue is empty, dequeue operation is not allowed!')
        element = self._data[self._front]
        self._data[self._front] = None
        self._front = (self._front + 1) % len(self._data)
        self._size -= 1
        if self._size == self.get_capacity() // 4 and self.get_capacity() // 2 != 0:
            self._resize(self.get_capacity() // 2)
        if self._size == 0:
            self._front, self._tail = None, None
        return element

    def get_front(self):
        return self._data[self._front]

    def get_size(self):
        return self._size

    def is_empty(self):
        return self._size == 0

    def get_capacity(self):
        return len(self._data)

    def _resize(self, new_capacity):
        new_data = [None] * new_capacity
        for i in range(self._size):
            new_data[i] = self._data[(i+self._front) % len(self._data)]
        self._data = new_data
        self._front = 0
        self._tail = self._size - 1


if __name__ == '__main__':
    queue = LoopQueue()
    for x in range(10):
        queue.enqueue(x)
    print(queue)
    queue.dequeue()
    print(queue)
    queue.dequeue()
    print(queue)
    queue.dequeue()
    print(queue)
    for x in range(100, 110):
        queue.enqueue(x)
        print(queue)

    # for x in range(25):
    #     queue.enqueue(x)
    #     print(queue)
    # for x in range(25):
    #     queue.dequeue()
    #     print(queue)
写回答

2回答

liuyubobobo

2019-09-13

没有问题,利用 size 而不是 front 和 tail,可以做到不浪费一个空间:)


感谢分享,继续加油!:)


中秋快乐!:)

0
0

慕尼黑7895541

2019-09-27

兄弟 可以写一份java的吗

0
1
Aioria_
好几年没写java代码了,有些生疏了,需要的话给你写一遍kotlin的
2019-09-28
共1条回复

玩转数据结构

动态数组/栈/队列/链表/BST/堆/线段树/Trie/并查集/AVL/红黑树…

6221 学习 · 1704 问题

查看课程