我正在写一个名为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()
答案 0 :(得分:3)
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所以我们移动到代码的第二行,这是第一个递归调用to head.next,这是2.再次,我们看到这个新的" head"不等于null,所以我们做第二次递归调用,这次传递包含3的节点。我们看到这个新的" head"不等于null,所以我们在head.next上进行第三次递归调用,在这种情况下为null。所以我们回来了,因为我们遇到了基础案例。我们现在回到第二次递归调用,然后移动到递归调用之后的代码行,即print语句。我们打印3.由于这个递归调用现在已经完成,我们将回到第一个递归调用,然后打印2.最后,我们回到初始函数调用,然后打印1.因此,成功打印我们的链接列表订购。
答案 1 :(得分:2)
好吧,除非你有一个双链表,你最好的选择是遍历整个链表,保存内存中的所有内容,然后打印出来。
这可能是您的代码草稿:
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。
答案 2 :(得分:2)
我希望您的问题是因为没有有效的方法可以在单链列表上向后迭代。
我通过使用一些神奇的方法(又名dunder方法)略微增强了你的代码:名称(通常)以双下划线开头和结尾的方法。您可以在Special method names下的文档中了解它们。
当对象传递给__str__
内置函数时,会调用对象的str
方法(当您尝试打印对象时会隐式发生这种情况)。如果对象没有__str__
方法,则调用其__repr__
方法;通常最好定义这两种方法中的至少一种,否则当您尝试打印对象时,将调用从通用__repr__
继承的默认object
方法。
我已将您的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
答案 3 :(得分:0)
您可以通过使用两个循环来实现。一个用于循环整个列表,另一个用于相对于主循环转到特定节点并进行打印。 Count()返回节点数。当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)