[英]A method to print linked list in reverse/backward order in python
我正在编写一个名为 LList 的类,并在该类中定义了几个方法。 我在编写一种以倒序方式打印链表的方法时遇到问题。
class Node(object):
def __init__(self, data=None, nextNode=None):
self.data = data
self.nextNode = nextNode
class LList(object):
def __init__(self, head=None):
self.head = head
self.size = 0
def insert(self, node):
if not self.head:
self.head = node
self.size += 1
else:
# set new nodes pointer to old head
node.nextNode = self.head
# reset head to new node
self.head = node
self.size +=1
def getSize(self):
return self.size
def printLL(self):
mynode = self.head
c = 0
while mynode:
c += 1
print(mynode.data, c)
mynode = mynode.nextNode
#a method for class that prints list backwards.
def reverse(self):
#main program
MyList = LList()
MyList.insert(Node("NJ"))
MyList.insert(Node("NR"))
MyList.insert(Node("OH"))
# Use my print method
MyList.printLL()
#print in reverse
MyList.reverse()
class Node(object):
def __init__(self, data=None, next_node=None):
self.data = data
self.next = next_node
def ReversePrint(head):
if head == None:
return
else:
ReversePrint(head.next)
print(head.data)
让我们以链表为例: 1->2->3 遍历代码,函数 ReversePrint 被赋予了一个指向链表头部的链接,即 1。我们看到头部不等于 null 所以我们移动到代码的第二行,这是对 head.next 的第一次递归调用,即 2。我们再次看到这个新的“head”不等于 null,因此我们进行了第二次递归调用,这次传递了包含 3 的节点。我们看到这个新的“head”不等于 null,所以我们对 head.next 进行第三次递归调用,在这种情况下它是 null。 所以我们回来了,因为我们达到了我们的基本情况。 现在我们又回到了第二个递归调用中,我们移到递归调用之后的代码行,即打印语句。 我们打印 3。由于这个递归调用现在已经完成,我们回到第一个递归调用,并打印 2。最后,我们回到最初的函数调用,我们打印 1。因此,成功地反向打印我们的链表命令。
好吧,除非你有一个双链表,否则最好的选择是遍历整个链表,将所有内容保存在内存中,然后打印出来。
这可能是您的代码草稿:
def print_reversed(self):
node = self.head
values = []
while node:
values.append(node.data)
node = node.nextNode
for value in reversed(values):
print(value)
这在某种程度上违背了链表的目的。 您也可以递归地执行此操作,但这在 IMO 中看起来很混乱。
我希望您的问题是由于没有有效的方法来向后迭代单链表。
我通过使用一些魔术方法(又名dunder方法)稍微增强了您的代码:名称(通常)以双下划线开头和结尾的方法。 您可以在特殊方法名称下的文档中阅读有关它们的信息。
对象的__str__
方法在对象传递给str
内置函数时被调用(当您尝试打印对象时会隐式发生)。 如果一个对象不具有__str__
方法,其__repr__
方法被调用; 通常最好至少定义这两种方法中的一种,否则当您尝试打印对象时,将从通用object
继承的默认__repr__
方法将被调用。
我已将您的getSize
方法更改为__len__
,当将对象传递给len
内置函数时会调用该方法。
一个对象的__iter__
方法在它被传递给iter
内置函数时被调用,无论是显式的,还是当你试图在某种for
循环中迭代对象时,或者当你将它传递给list
或类似的构造函数时。 它通常与__next__
方法结合使用,该方法(不幸的是)在 Python 2 中命名为next
。当一个对象具有这些方法时,以各种方式对其进行迭代是相对容易的。
要进行反向打印,我们可以简单地将实例传递给list
,并将结果列表传递给reversed
,它返回一个迭代器,该迭代器在其列表参数上向后迭代。
下面的代码是为 Python 2 编写的; 对于 Python 3,将next
方法更改为__next__
。
class Node(object):
def __init__(self, data=None, nextNode=None):
self.data = data
self.nextNode = nextNode
def __str__(self):
return str(self.data)
class LList(object):
def __init__(self):
self.head = None
self.current = None
self.size = 0
def insert(self, node):
if self.head is not None:
# set new node's pointer to old head
node.nextNode = self.head
self.head = node
self.size += 1
def __len__(self):
return self.size
def __iter__(self):
self.current = self.head
return self
def next(self):
current = self.current
if current is None:
raise StopIteration
else:
self.current = current.nextNode
return current
def printLL(self):
for i, node in enumerate(self, 1):
print(node, i)
# print the list backwards
def reverse_print(self):
c = len(self)
for node in reversed(list(self)):
print(node, c)
c -= 1
# main program
mylist = LList()
mylist.insert(Node("NJ"))
mylist.insert(Node("NR"))
mylist.insert(Node("OH"))
print(len(mylist))
# print forwards
mylist.printLL()
#print the nodes using a list comprehension
print([str(node) for node in mylist])
#print in reverse
mylist.reverse_print()
输出
3
OH 1
NR 2
NJ 3
['OH', 'NR', 'NJ']
NJ 3
NR 2
OH 1
您可以通过使用两个循环来实现它。 一个用于循环整个列表,另一个用于转到与主循环相关的特定节点并打印它。 Count() 返回节点数。 当计数为 0 值时,节点循环在最后一个节点处停止,因为 (self.Count() - count) 并打印它。 就这样倒退了。
def reverse(self):
for count in range(self.Count()+1):
iteration = 0
printval = self.head
while printval != None:
if iteration == (self.Count() - count):
break
printval = printval.next
iteration = iteration + 1
print(printval.name)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.