【问题标题】:recursion in sorted double linked list insertion排序双链表插入中的递归
【发布时间】:2018-05-15 23:17:39
【问题描述】:

我是数据结构和递归概念的新手。我很难理解他为什么以及谁能够在这个概念中使用递归。我在论坛中找到了此代码,但我无法真正理解它的概念。对于 2 1 3 4 的简单情况,如果有人能解释迭代步骤,我将不胜感激。

这是黑客等级的链接: https://www.hackerrank.com/challenges/insert-a-node-into-a-sorted-doubly-linked-list

Node SortedInsert(Node head,int data) {
    Node n = new Node();
    n.data = data;
    if (head == null) {
        return n;
    }
    else if (data <= head.data) {
        n.next = head;
        head.prev = n;
        return n;
    }
    else {
        Node rest = SortedInsert(head.next, data);
        head.next = rest;
        rest.prev = head;
        return head;
    }
}

【问题讨论】:

  • 从你的大脑中删除这段代码,永远不要重新访问它。这会像疯了似的泄漏,并有可能在长列表中出现堆栈溢出。
  • 谢谢阿德里安。感谢您的回复。

标签: algorithm recursion data-structures doubly-linked-list insertion


【解决方案1】:

递归: 递归意味着函数调用自身。对于需要保存多个状态(通常是大量状态)并以相反顺序检索它们的算法,它被用作保存状态信息的简单方法。 (还有一些更专业且不易出现内存问题的替代技术,例如使用 Stack 对象来保存程序状态)。

这个例子很糟糕,但是典型的递归介绍。是的,您可以使用递归遍历链表,但绝对没有理由这样做。一个循环会更合适。这纯粹是为了演示递归是如何工作的。所以,回答你的问题“为什么?”它只是让您可以学习这个概念,然后在其他算法中使用它,这实际上是有意义的。

当您拥有一棵树而不是链表时,递归很有用,其中每个节点都指向多个其他节点。在这种情况下,您需要保存您的状态(您所在的节点,以及您最后调用的子节点),以便您可以遍历其中一个链接节点,然后返回并转到下一个节点。

您还问过“如何”。当一个函数调用自己时,它的所有变量都被保存(在程序堆栈上),并为自己的下一次迭代创建新变量。然后,当该调用返回时,它会返回到调用它的位置并加载前一组变量。这与“跳转”或某种循环非常不同,其中每次都使用相同的变量副本。通过使用递归,每次调用每个局部变量都会有一个新副本。即使对于示例中的“数据”变量也是如此,它永远不会改变(因此,效率低下)。

【讨论】:

  • 谢谢加尔。感谢您的回复和 cmets。这是有道理的。我将阅读更多关于此的材料。我想做更多关于递归的例子,只是掌握这个概念,这样我就可以调试和迭代,看看自己会发生什么。你能推荐一些这样的例子吗?我尝试过对阶乘和斐波那契数列进行递归。
  • 这里有一个有趣的。将 x^N 视为递归问题。当然,你可以循环 1..N,这是 N 次乘法,但是你可以通过分解问题来减少它,因为 x^N = x^(N/2) * x^(N-(N/2) )。您可以递归调用每一边(如果 N 为偶数,则只调用一个)并将结果相乘。必须是特殊情况 N=0,N=1 并且可能是 N=2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 2015-07-07
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多