Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将LinkedList类转换为循环链表类的最简单方法是什么?_Python_Python 3.x_Linked List - Fatal编程技术网

Python 将LinkedList类转换为循环链表类的最简单方法是什么?

Python 将LinkedList类转换为循环链表类的最简单方法是什么?,python,python-3.x,linked-list,Python,Python 3.x,Linked List,我有一个LinkedList类,它有将近200行代码。我想创建一个新的类LLCircular(LinkedList),始终确保任何myLL.tail.next都是myLL.head。我相信我需要相应地更新append(),push(),remove(),等等。有没有一种方法可以保持原始LinkedList类的完整性?也许是一个装饰师或是一个dunder的方法 为了简洁起见,如果读取代码,我的push()方法正好与append()相反。我还有一个pop()和remove()方法,如果我只是重写这些

我有一个LinkedList类,它有将近200行代码。我想创建一个新的
类LLCircular(LinkedList)
,始终确保任何
myLL.tail.next都是myLL.head
。我相信我需要相应地更新
append()
push()
remove()
,等等。有没有一种方法可以保持原始LinkedList类的完整性?也许是一个装饰师或是一个dunder的方法

为了简洁起见,如果读取代码,我的
push()
方法正好与
append()
相反。我还有一个
pop()
remove()
方法,如果我只是重写这些方法,则需要对其进行更新。由于我试图避免这种做法,我不会发布代码的这一部分

class LinkedListNode:
   def __init__(self, value, nextNode=None, prevNode=None):
      self.value  = value
      self.next   = nextNode
      self.prev   = prevNode
   def __str__(self):
      return str(self.value)

class LinkedList:
   def __init__(self, values=None):
      self.head   = None
      self.tail   = None
      if values is not None:
         self.append(values)
   def __str__(self):
      values = [str(x) for x in self]
      return ' -> '.join(values)
   def append(self, value=None):
      if value is None:
         raise ValueError('ERROR: LinkedList.py: append() `value` PARAMETER MISSING')
      if isinstance(value, list):
         for v in value:
            self.append(v)
         return
      elif self.head is None:
         self.head   = LinkedListNode(value)
         self.tail   = self.head
      else:
         ''' We have existing nodes  '''
         ''' Head.next is same '''
         ''' Tail is new node '''
         self.tail.next = LinkedListNode(value, None, self.tail)
         self.tail      = self.tail.next
         if self.head.next is None:
            self.head.next = self.tail.prev
      return self.tail

'''class LLCircular(LinkedList):'''
    ''' ??? '''
测试代码:

foo = LinkedList([1,2,3])
foo.tail.next = foo.head #My LL is now circular
cur = foo.head
i = 0
while cur:
   print(cur)
   cur = cur.next
   i +=1
   if i>9:
      break

您需要使用
super
关键字调用
LinkedList
基类函数,然后对
LLCircular
类函数添加细微修改,即:

class LLCircular(LinkedList):
    def append(self, value=None):
        super(LLCircular, self).append(value)
        # In addition to having called the LinkedList append, now you want
        # to make sure the tail is pointing at the head
        self.tail.next = self.head
        self.head.prev = self.tail

您需要使用
super
关键字调用
LinkedList
基类函数,然后对
LLCircular
类函数添加细微修改,即:

class LLCircular(LinkedList):
    def append(self, value=None):
        super(LLCircular, self).append(value)
        # In addition to having called the LinkedList append, now you want
        # to make sure the tail is pointing at the head
        self.tail.next = self.head
        self.head.prev = self.tail
如果它是“圆形”的,它就不需要尾巴或头了,是吗? “追加”也没有意义-在方法之后插入\u和在方法之前插入\u就足够了-而且,任何节点都是对完整循环列表的引用,不需要不同的对象:

class Circular:
    def __init__(self, value=None):
        self.value = value
        self.next = self
        self.previous = self
    def insert_after(self, value):
        node = Circular(value)
        node.next = self.next
        node.previous = self
        self.next.previous = node
        self.next = node
    def insert_before(self, value):
        node = Circular(value)
        node.next = self
        node.previous = self.previous
        self.previous.next = node
        self.previous = node
    def del_next(self):
        self.next = self.next.next
        self.next.previous = self
    def __iter__(self):
        cursor = self.next
        yield self
        while cursor != self:
             yield cursor
             cursor = cursor.next
    def __len__(self):
        return sum(1 for _ in self)
如果它是“圆形”的,它就不需要尾巴或头了,是吗? “追加”也没有意义-在方法之后插入\u和在方法之前插入\u就足够了-而且,任何节点都是对完整循环列表的引用,不需要不同的对象:

class Circular:
    def __init__(self, value=None):
        self.value = value
        self.next = self
        self.previous = self
    def insert_after(self, value):
        node = Circular(value)
        node.next = self.next
        node.previous = self
        self.next.previous = node
        self.next = node
    def insert_before(self, value):
        node = Circular(value)
        node.next = self
        node.previous = self.previous
        self.previous.next = node
        self.previous = node
    def del_next(self):
        self.next = self.next.next
        self.next.previous = self
    def __iter__(self):
        cursor = self.next
        yield self
        while cursor != self:
             yield cursor
             cursor = cursor.next
    def __len__(self):
        return sum(1 for _ in self)

我已经做了大约4个月的Android/Java开发了,我很震惊我之前没有想到这一点::joy::谢谢
\uuuuu init\uuuuuu
不需要被覆盖,如果它所做的只是调用链的更高一级的
\uuuuuuu init\uuuuuu
。是否应该将
self.head.prev
设置为新的尾部?@t.Woody是的,这取决于您的列表是否应该是“双链接”的,如果只在一个方向上遍历,则不需要进行遍历。请注意,可能需要更新
self.tail.next
self.head.prev
的唯一原因是将节点添加到空列表中;关于
LinkedList.append的任何内容都不会破坏现有的循环链接列表。在实现中使用适当的“虚拟”节点,这样即使是“空”列表也能包含某些内容,即使是这种特殊情况也可以避免。我已经做了大约4个月的Android/Java开发,我很震惊我之前没有想到这一点::joy::谢谢
\uuuuu init\uuuuuu
不需要被覆盖,如果它所做的只是调用链的更高一级的
\uuuuuuu init\uuuuuu
。是否应该将
self.head.prev
设置为新的尾部?@t.Woody是的,这取决于您的列表是否应该是“双链接”的,如果只在一个方向上遍历,则不需要进行遍历。请注意,可能需要更新
self.tail.next
self.head.prev
的唯一原因是将节点添加到空列表中;关于
LinkedList.append的任何内容都不会破坏现有的循环链接列表。在实现中使用适当的“虚拟”节点,这样即使“空”列表包含某些内容,也可以摆脱这种特殊情况;非常感谢。我应该更具体地说,我希望将此作为现有LinkedList类的循环列表,以避免编写一个完整的新类。如果您喜欢,您可以对此进行更新投票,并保持另一个被接受;非常感谢。我应该更具体地说,我希望将此作为现有LinkedList类的循环列表,以避免编写一个完整的新类。如果您喜欢,您可以对此进行更新,并保留另一个作为可接受的。