在python中的循环链接列表中出队

时间:2019-03-07 15:25:18

标签: python linked-list queue

我正在使用python中的循环链接列表来实现Queue的实现。以下是循环LinkedList的图形表示

css-tricks.com

除了出队例程,我能够实现大多数代码。在出队例程中,必须跟踪相对于当前节点的上一个节点参考以及下一个节点参考。在双链表中,很容易实现。但是,我不知道如何在单个链接列表中实现此概念。

class CircularQueue:

  ''' Queue implementation using a Circularly linked list for storage '''

  class _Node:

      __slots__ == '_element','_next'

      def __init__(self,element,next):            
        self._element = element 
        self._next = next 

  def __init__(self):
    '''Create an empty queue'''
    self._current = None 
    self._size = 0

  def __len__(self):
    return self._size

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

  def enqueue(self,e):

    node = self._Node(e,None)
    if self.is_empty():
        newest._next = newest
    else:
        curr_node = self._current._next 
        node._next = curr_node
    self._current = node 
    self._size += 1

  def dequeue(self):
    if self.is_empty():
        raise Empty('Stack is empty')

如果有人可以给我关于如何在出队例程中前进的想法,这会更有帮助。

1 个答案:

答案 0 :(得分:0)

由于链接列表是单向的,因此元素仅引用了它的后继元素,而从未引用过它的前任元素,为了使列表中的元素出队容易,您需要同时使用这两个元素。

我看到两种可能性:您可以使链表成为双向的,因此可以添加对前一个元素的引用。我对您的实现进行了一些整理,希望您仍然可以这样做:

""" Queue implementation using a Circularly linked list for storage """


class _Node:
    def __init__(self, element, next=None, previous=None):
        self.element = element
        if next is None:
            next = self
        self.next = next
        if previous is None:
            previous = self
        self.previous = previous


class CircularQueue:
    def __init__(self):
        self._current = None
        self._size = 0

    def __len__(self):
        return self._size

    def get_head(self):
        return self._current.element

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

    def next(self):
        self._current = self._current.next
        return self._current.element

    def previous(self):
        self._current = self._current.pevious
        return self._current

    def enqueue(self, element):
        """ Adds an element at the current position, ahead of the current element """
        if self.is_empty():
            new_node = _Node(element)
        else:
            new_node = _Node(element, self._current.next, self._current)
            self._current.next = new_node
        self._current = new_node
        self._size += 1

我们现在可以检查我们的代码是否正确:

cq = CircularQueue()
cq.enqueue("A")
cq.enqueue("B")
cq.enqueue("C")

print(cq.get_head())
print(cq.next())
print(cq.next())
print(cq.next())

然后您将看到C,A,B和C连续打印。

双边队列使我们能够实现这样的出队方法:

def dequeue(self, element_key=None):
    if self.is_empty():
        raise KeyError('Stack is empty')

    if element_key is None:
        self._current.next.previous = self._current.previous
        self._current.previous.next = self._current.next
        return self.next()
    else:
        current = self._current
        while self._current.element != element_key:
            self.next()
            if self._current == current:
                raise KeyError('Element not found')
        self.dequeue()

如果我们对其进行测试...

print("dequeuing 'B'")
cq.dequeue("B")
print(cq.get_head())
print(cq.next())
print(cq.next())
print(cq.next())

...我们应该看到打印了“使'B'出队”,以及C,A,C和A再次被打印,这使我们感到高兴。 :)

也可以使用单方面的方法;您可能会花很少的时间来处理参考,而您会遍历整个圈子(在最坏的情况下)。首先,您将跳到队列中的下一个元素,直到当前元素的下一个元素是您要出队的元素,然后将当前元素的下一个引用设置为已出队的下一个元素,基本上已经完成。