如何在 python 中使此代码成为反向循环 LL 的缩写
how to make this code short for reverse circular LL in python
class node:
def __init__(self,data):
self.data = data
self.next = None
class circularLL:
def __init__(self):
self.head = None
self.tail = None
def insertNode(self,data):
newnode = node(data)
if self.head is None:
self.head = newnode
self.tail = newnode
else:
newnode.next = self.head
tail = self.tail
tail.next = newnode
self.tail = tail.next
def printCLL(self):
current = self.head
while current.next is not None and current.next is not self.head:
print(current.data, end="----")
current = current.next
print(current.data)
def reverseCLL(self):
head = self.head
tail = self.tail
if head == tail:
return
else:
count = 0
while head.next is not tail:
count +=1
if count ==1:
next = head.next
prev = head
head.next = tail
newtail = head
head = next
else:
next = head.next
head.next = prev
prev = head
head = next
if count is not 0:
next = head.next
head.next = prev
prev = head
tail.next = prev
self.head = tail
self.tail = newtail
else:
head.next = tail
self.tail.next = head
self.head = tail
self.tail = head
c = circularLL()
c.insertNode(1)
c.printCLL()
c.insertNode(2)
c.insertNode(3)
c.insertNode(4)
c.insertNode(5)
c.insertNode(6)
c.printCLL()
c.reverseCLL()
c.printCLL()
我写了一个循环链表的代码。但我认为反向部分可以更短,那么如何使反向部分更短呢?还有什么选择可以做到这一点???
谁能告诉我,当我对一个对象使用赋值运算符时,该变量指向该原始对象,或者该对象副本被分配给该变量的内存位置??
您的代码中仍然存在一些问题:
添加第一个节点时,该节点的 next
引用留给 None
,这意味着列表不是真正的循环。你实际上应该 永远不会 有一个节点,其 next
引用是 None
,所以我建议更改 Node
构造函数,这样它就不会' t 分配该值,而是使节点自引用 (self.next = self
)。这也意味着您可以从代码中删除大部分 None
检查。
当列表为空时,printCLL
方法失败。它应该首先检查该条件。
在与文字进行比较时,不应使用 is not
。所以改为 if count != 0:
甚至 if count:
一些其他备注:
class 名称使用 PascalCase 是常见的做法,因此 Node
而不是 node
和 CircularLL
而不是 circularLL
.
如同在一个循环中,non-emptylist 头节点总是在尾节点之后,没有真正需要单独存储对头节点的引用。你只需要 self.tail
.
因为class这个名字已经很清楚的表明我们处理的是一个循环链表,所以方法名中不需要有CLL
后缀。出于类似的原因,我只调用插入方法 insert
.
与其提供打印方法,不如提供 __repr__
方法,本机 print
函数将在存在时调用该方法。
通过定义一个__iter__
方法使链表实例可迭代。那么上面的__repr__
也可以靠那个
关于您问题的核心:是的,可以大大减少这段用于反转列表的代码。不需要计数器。
建议代码:
class Node:
def __init__(self,data):
self.data = data
self.next = self
class CircularLL:
def __init__(self):
self.tail = None
def insert(self, data):
newnode = Node(data)
if self.tail:
newnode.next = self.tail.next
self.tail.next = newnode
self.tail = newnode
def __iter__(self):
if not self.tail:
return
current = self.tail
while current.next is not self.tail:
current = current.next
yield current.data
yield current.next.data
def __repr__(self):
return "----".join(map(repr, self))
def reverse(self):
tail = self.tail
if not tail:
return
prev = tail
curr = prev.next
self.tail = curr
while curr != tail:
curr.next, prev, curr = prev, curr, curr.next
curr.next = prev
c = CircularLL()
c.insert(1)
print(c)
c.insert(2)
c.insert(3)
c.insert(4)
c.insert(5)
c.insert(6)
print(c)
c.reverse()
print(c)
class node:
def __init__(self,data):
self.data = data
self.next = None
class circularLL:
def __init__(self):
self.head = None
self.tail = None
def insertNode(self,data):
newnode = node(data)
if self.head is None:
self.head = newnode
self.tail = newnode
else:
newnode.next = self.head
tail = self.tail
tail.next = newnode
self.tail = tail.next
def printCLL(self):
current = self.head
while current.next is not None and current.next is not self.head:
print(current.data, end="----")
current = current.next
print(current.data)
def reverseCLL(self):
head = self.head
tail = self.tail
if head == tail:
return
else:
count = 0
while head.next is not tail:
count +=1
if count ==1:
next = head.next
prev = head
head.next = tail
newtail = head
head = next
else:
next = head.next
head.next = prev
prev = head
head = next
if count is not 0:
next = head.next
head.next = prev
prev = head
tail.next = prev
self.head = tail
self.tail = newtail
else:
head.next = tail
self.tail.next = head
self.head = tail
self.tail = head
c = circularLL()
c.insertNode(1)
c.printCLL()
c.insertNode(2)
c.insertNode(3)
c.insertNode(4)
c.insertNode(5)
c.insertNode(6)
c.printCLL()
c.reverseCLL()
c.printCLL()
我写了一个循环链表的代码。但我认为反向部分可以更短,那么如何使反向部分更短呢?还有什么选择可以做到这一点??? 谁能告诉我,当我对一个对象使用赋值运算符时,该变量指向该原始对象,或者该对象副本被分配给该变量的内存位置??
您的代码中仍然存在一些问题:
添加第一个节点时,该节点的
next
引用留给None
,这意味着列表不是真正的循环。你实际上应该 永远不会 有一个节点,其next
引用是None
,所以我建议更改Node
构造函数,这样它就不会' t 分配该值,而是使节点自引用 (self.next = self
)。这也意味着您可以从代码中删除大部分None
检查。当列表为空时,
printCLL
方法失败。它应该首先检查该条件。在与文字进行比较时,不应使用
is not
。所以改为if count != 0:
甚至if count:
一些其他备注:
class 名称使用 PascalCase 是常见的做法,因此
Node
而不是node
和CircularLL
而不是circularLL
.如同在一个循环中,non-emptylist 头节点总是在尾节点之后,没有真正需要单独存储对头节点的引用。你只需要
self.tail
.因为class这个名字已经很清楚的表明我们处理的是一个循环链表,所以方法名中不需要有
CLL
后缀。出于类似的原因,我只调用插入方法insert
.与其提供打印方法,不如提供
__repr__
方法,本机print
函数将在存在时调用该方法。通过定义一个
__iter__
方法使链表实例可迭代。那么上面的__repr__
也可以靠那个
关于您问题的核心:是的,可以大大减少这段用于反转列表的代码。不需要计数器。
建议代码:
class Node:
def __init__(self,data):
self.data = data
self.next = self
class CircularLL:
def __init__(self):
self.tail = None
def insert(self, data):
newnode = Node(data)
if self.tail:
newnode.next = self.tail.next
self.tail.next = newnode
self.tail = newnode
def __iter__(self):
if not self.tail:
return
current = self.tail
while current.next is not self.tail:
current = current.next
yield current.data
yield current.next.data
def __repr__(self):
return "----".join(map(repr, self))
def reverse(self):
tail = self.tail
if not tail:
return
prev = tail
curr = prev.next
self.tail = curr
while curr != tail:
curr.next, prev, curr = prev, curr, curr.next
curr.next = prev
c = CircularLL()
c.insert(1)
print(c)
c.insert(2)
c.insert(3)
c.insert(4)
c.insert(5)
c.insert(6)
print(c)
c.reverse()
print(c)