当前位置: 首页 > 知识库问答 >
问题:

使用递归反转单链表

姚韬
2023-03-14

我做了一个使用递归方法反转单链表的函数。然而,我在执行下面的代码时遇到了一些困难:

class node:
    def __init__(self,data=None):
        self.next=None
        self.data=data

class linked_list:
    def __init__(self):
        self.head=node()

def append(self,data):
    new_node=node(data)
    cur_node=self.head
    while (cur_node.next!=None):
        cur_node=cur_node.next
    cur_node.next=new_node
    return cur_node.data

def display(self):
    elements=[]
    cur_node=self.head
    while(cur_node.next!=None):
        cur_node=cur_node.next
        elements.append(cur_node.data)
    print(elements)

def reverseRecursive(self,prev_code,cur_node):
    if cur_node.next!=None:
        reverseRecursive(cur_node,cur_node.next)
        cur_node.next=prev_node
    else:
        self.head=cur_node
    return
lst1=linked_list()
lst1.display()
lst1.append(1)
lst1.append(3)
lst1.append(5)
lst1.append(7)
lst1.display()
lst1.reverseRecursive(None,_____)
lst1.display()

我应该如何在ReverseCursive函数/方法中传递第二个参数,以便执行它?

作为第二个参数,我想简单地传递链表的头节点。但是我不知道如何从类的init方法中获取头节点linked_list

我试了几件事,但都解决不了。也许我不太擅长OOP概念。有人能帮我解决这个问题吗?

共有1个答案

秦俊发
2023-03-14

链表是一种递归结构,因此将其与函数式风格结合使用将产生最佳效果。在您的程序中,您已经使用程序样式和可变节点实现了一个链表–您可以随时间更改数据下一步的值。虽然这可能感觉像是一种直观的方法,但我想专注于一个不变的规则,它将我们从严重的状态复杂性中解放出来。

首先,我们修复节点构造函数。我们在构建新节点时设置了这两个属性,因为它们在程序中不会发生更改——

class node:
  def __init__ (self, data, next):
    self.data = data
    self.next = next

那么一个linked_list只是一个由特定约定构造的节点:

  • 节点。数据保留节点的数据

我们从linked_list的构造函数开始-

class linked_list:
  def __init__ (self, node = None):
    self.node = node

  # ...

实现是空的,和属性来提取节点——

class linked_list:
  def __init__ (self, node = None):
    self.node = node

  @property
  def is_empty (self):
    return self.node is None

  @property
  def head (self):
    if self.is_empty:
      raise Exception ("cannot get head of an empty list")
    else:
      return self.node.data

  @property
  def tail (self):
    if self.is_empty:
      raise Exception ("cannot get tail of an empty list")
    else:
      return self.node.next

现在节点的使用完全抽象,我们可以通过使用我们的新属性编写更高级别的列表行为-

class linked_list:
  ... 

  def length (self):
    if self.is_empty:
      return 0
    else:
      return 1 + self.tail.length()

上面,我们看到通过使用它的属性来谈论我们的列表是非常容易的。在我们深入之前,让我们看看如何构建列表并使用print将其可视化。对于对象到字符串转换,我们使用__str__-

class linked_list:
  ... 

  def add (self, x):
    return linked_list (node (x, self))

  def __str__ (self):
    if self.is_empty:
      return "None"
    else:
      return str (self.head) + " -> " + str (self.tail)

ls = linked_list().add('A').add('B').add('C')
print (ls)
# C -> B -> A -> None

print (ls.length())
# 3

请记住,因为我们构建了一个不可变的链表,add不会更改它被调用的列表——

ls = linked_list().add('A').add('B').add('C')
print (ls)
# C -> B -> A -> None

print (ls.add('D'))
# D -> C -> B -> A -> None

print (ls)
# C -> B -> A -> None

最后,我们可以实现反向——

class linked_list:

  # ...

  def reverse (self):
    def loop (ls, acc):
      if ls.is_empty:
        return acc
      else:
        return loop (ls.tail, acc.add(ls.head))
    return loop (self, linked_list())

ls = linked_list().add('A').add('B').add('C')
print (ls)
# C -> B -> A -> None

print (ls.reverse())
# A -> B -> C -> None

颠倒列表不会改变它

print (ls)
# C -> B -> A -> None

print (ls.reverse())
# A -> B -> C -> None

print (ls)
# C -> B -> A -> None
 类似资料:
  • 本文向大家介绍单链表反转 递归法Java实现相关面试题,主要包含被问及单链表反转 递归法Java实现时的应答技巧和注意事项,需要的朋友参考一下 经历了很多面试,面试官最爱考察的算法无非是斐波那契数列和单链表反转,尽管是这些都是基础知识,然而我对单链表反转有更多的想法。 递归法是我早期最爱在面试中使用的算法,很有逼格,写起来非常优雅,非常好理解。 先定义链表数据结构 如上代码所示 递归法会逐层确定该

  • 还缺少的是将最后一个节点的next赋值为NULL。 在任何世界里,像这样的东西会起作用吗?它给出了一个运行时/分段错误。

  • 我仍然在努力用递归技术来解决这个问题。我知道下面有更好的方法来解决我的问题,即反转链表。我见过的大多数方法都是通过从头到尾开始反转指针,或者使用迭代或递归。 我试图通过递归查找列表中的最后一个节点,然后每次函数返回时都更改指针来反转列表。 下面我到底做错了什么?或者这种方法甚至可以工作,而不需要向递归函数传递更多参数?提前感谢您的帮助。 编辑:另一次尝试 最终解决了:

  • 我试图以相反的顺序打印一个链表,但实际上没有使用递归进行反转,但我的输出结果非常奇怪。看起来我的代码基本上选择了第一个节点,并在打印完链表的其余部分(按原始顺序)后将其打印出来。我所写的代码(据我所知)是正确的,并且与internet上解决此问题的代码相匹配。 这是我的代码: 以下是节点类: 这是我给出的输入,然后是输出: 这里发生的另一个奇怪的事情是,如果我改变递归的条件,假设我这样做: 然后是

  • 问题内容: 我已经在一个类的Java项目上工作了一段时间。它是链表(此处称为,包含称为的简单节点)的实现。问题是,一切都必须使用递归算法来完成。我可以用一种方法来做所有的事情: 现在,我的函数只是调用一个带有参数以允许递归的辅助函数。 我的助手功能具有的签名。 目前,我使用堆栈来迭代工作,但这不是规范所要求的。我在C语言中找到了一种算法,该算法可以递归地将其递归逆转并将其转换为Java代码,并且可