[英]How can I write a recursive function to reverse a linked list?
我想用 Python 来做。我不想只是反向打印它,而是实际上反转给定的节点。 我见过用其他语言完成的,但在 Python 中找不到示例。
我正在尝试在一个 function 中完成此操作,但如果需要一个助手 function,那就这样吧。
def reverse (item, tail = None):
next = item.next
item.next = tail
if next is None:
return item
else:
return reverse(next, item)
使用这样一个简单的链表实现:
class LinkedList:
def __init__ (self, value, next = None):
self.value = value
self.next = next
def __repr__ (self):
return 'LinkedList({}, {})'.format(self.value, repr(self.next))
例子:
>>> a = LinkedList(1, LinkedList(2, LinkedList(3, LinkedList(4))))
>>> a
LinkedList(1, LinkedList(2, LinkedList(3, LinkedList(4, None))))
>>> b = reverse(a)
>>> b
LinkedList(4, LinkedList(3, LinkedList(2, LinkedList(1, None))))
>>> a # note that there is a new head pointer now
LinkedList(1, None)
我创建了一个使用递归的反向方法的链表的简单实现。
class Node(object):
def __init__(self,initdata):
self.data = initdata
self.next = None
class LinkedList(object):
def __init__(self):
self.head = None
def isEmpty(self):
return self.head == None
def add(self,data): #this method adds node at head
temp = Node(data)
temp.setNext(self.head)
self.head = temp
def traverse(self):
current = self.head
while current:
if current.getNext():
print(current.data,end="->")
else:
print(current.data)
current = current.getNext()
def reverse(self,item):
if item.next == None:
self.head = item
return
self.reverse(item.next)
temp = item.next
temp.next = item
item.next = None
def main():
mylist = LinkedList()
mylist.add(15)
mylist.add(20)
mylist.add(25)
mylist.add(30)
mylist.traverse()
mylist.reverse(mylist.head)
mylist.traverse()
print(mylist.head.data)
if __name__ == "__main__":
main()
输出:
Before:
30->25->20->15
After:
15->20->25->30
使用递归的另一种方法:
def reverse(head):
# Empty list is always None
if not head:
return None
# List of length 1 is already reversed
if not head.get_next():
return head
next = head.get_next()
head.set_next(None)
rest = reverse(next)
next.set_next(head)
return rest
在试图彻底了解如何使用迭代和递归方法在 Python 中反转链表并进行适当的重构之后,我编写了此代码。 我研究的许多链接似乎有点不清楚或有不必要的步骤。 如果我还没有达到最低限度/明确的步骤,我认为这些至少是接近的。 我觉得最好不要包含输出,但它会按原样运行并产生输出(python 2.7 并且易于修改 3.x)。
class Node:
def __init__(self,val):
self.val = val
self.next = None # the pointer initially points to nothing
def traverse(self):
# start from the head node
node = self
while node != None:
# access the node value
out_string = 'val = %d, loc = %s, next = %s'
print out_string % (node.val, node, node.next)
# move on to the next node
node = node.next
def reverse_iteratively(self):
previous = None
current = None
head = self
while head:
# before reverse
previous = current
current = head
head = head.next
# reverse the link
current.next = previous
def reverse_recursively(self, node, pre=None):
if node.next != None:
self.reverse_recursively(node.next, pre=node)
node.next = pre
### Operation Section
node0 = Node(0)
node1 = Node(7); node0.next = node1
node2 = Node(14); node1.next = node2
node3 = Node(21); node2.next = node3
node4 = Node(28); node3.next = node4
node5 = Node(35); node4.next = node5
node6 = Node(42); node5.next = node6
node7 = Node(49); node6.next = node7
node8 = Node(56); node7.next = node8
node9 = Node(63); node8.next = node9
print "Forward linked:"
node0.traverse()
node0.reverse_recursively(node0)
print "Reverse linked:"
node9.traverse()
对@Rajat Bhatt 实现稍作修改。 不同之处在于以下代码可以作为链表类之外的单独函数执行。
print '\n-- Initialize --'
lst = LinkedList(10) # 10 --> *
print '\n-- Insert --'
lst.append(20) # 10 --> 20 --> *
lst.append(30) # 10 --> 20 --> 30 --> *
lst.insertAt(15, pos=1) # 10 --> 15 --> 20 --> 30 --> *
lst.insertAt(25, pos=3) # 10 --> 15 --> 20 --> 25 --> 30 --> *
lst.insertAt(2) # 2 --> 10 --> 15 --> 20 --> 25 --> 30 --> *
lst.append(100) # 2 --> 10 --> 15 --> 20 --> 25 --> 30 --> 100 --> *
lst.append(500) # 2 --> 10 --> 15 --> 20 --> 25 --> 30 --> 100 --> 500 --> *
print lst
# 2 --> 10 --> 15 --> 20 --> 25 --> 30 --> 100 --> 500 --> *
print '\n-- Reverse using Recursion --'
def revFunc(curr):
if curr.next_node is None:
lst.head = curr
return None
revFunc(curr.next_node)
curr.next_node.next_node = curr
curr.next_node = None
revFunc(lst.head)
print lst
# Head --> 500 --> 100 --> 30 --> 25 --> 20 --> 15 --> 10 --> 2 --> *
def reverse_list(self,node):
if node is None:
return //list is empty
elif node.next is None:
self.head = node // changing the head to last node after reversal
return
else:
reverse_list(node.next) //call the function recursively until the end of the list
node.next.next = node //reverse the link
node.next = None
def reverse_ll_pass(self):
temp = self.head
if temp is None:
return
return self.reverse_ll_recursive(temp,past=None)
def reverse_ll_recursive(self,curr,past):
if curr is None:
self.head = past
return self.head
else:
future = curr.next
curr.next = past
past = curr
curr = future
return self.reverse_ll_recursive(curr,past)
与 poke 的解决方案非常相似,但我更喜欢先使用基本情况:
def reverse(head, reversed=None):
if head is None:
return reversed
new_head = head.next
head.next = reversed
new_reversed = head
return reverse(new_head, new_reversed)
两种可能的方法来实现这一点。
第一个,一旦找到head
,不依赖于类属性来保存head
。 它通过递归调用堆栈返回指向head
的指针
def reverseList(head):
# Empty list is always None
if not head:
return None
# List of length 1 is already reversed
if not head.next:
return head
next = head.next
head.next = None
rest = reverseList(next)
next.next = head
return rest
第二种解决方案,在您的类中使用指向head
的指针(类属性)
class Solution:
head: Optional[ListNode]
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
node = head
if node == None:
return node
if node.next == None:
self.head = node
return
self.reverseList(node.next)
q = node.next
q.next = node
node.next = None
return self.head
def reverse_linkedlist(node):
if node == None or node.next == None:
return node
else:
last_node = reverse_linkedlist(node.next)
new_head = node.next
new_head.next = node
node.next = None
return last_node
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.