【问题标题】:Minimum value in a Linked List. Incorrect recursive result?链表中的最小值。递归结果不正确?
【发布时间】:2016-11-28 16:20:08
【问题描述】:

试图复习一些概念。我试图找到链接列表实现中所有节点中存在的最小值。我认为出于某种原因,我的代码正在返回所有递归返回值,而不仅仅是最后一个。有人可以检查一下我的 findMin 方法中的问题吗?

public class Node
{
    public int data;
    public Node next;
    public Node(int d)
    {
        data = d;
        next = null;
    }
}



public static int findMin(Node head,int min=0)
{
    if (min == 0)
        min = head.data;
    if (head.data < min)
    {
        min = head.data;
    }
    else
    {
        findmin(head.next, min);
    }
    return min;
}

【问题讨论】:

  • 请尝试使用调试器。
  • 与问题本身没有直接关系,但为什么使用0作为min的默认值?我认为它应该是int.MaxValue,因为您正试图在列表中找到最小的元素。
  • 另外,您所说的“我认为出于某种原因我的代码返回所有递归返回值,而不仅仅是最后一个返回值”并不完全清楚。也许提供一个例子说明findMin() 为给定的数字列表返回什么?
  • C#汽车不敏感吗?你在哪里使用findmin返回的结果(可能的最小值)?
  • 我认为您使用递归而不是循环用于教育目的是否正确?因为如果不是,你不应该使用递归来解决这个问题。

标签: c# algorithm recursion data-structures


【解决方案1】:

我相信它会给你返回第一个元素。或者有时会崩溃。

if (min == 0) min = head.data; //true initially. min=first element
if (head.data < min) //false. We just assigned it, it does not get executed
{
    min = head.data;
}
else
{
    findmin(head.next, min); //this gets executed but result is ignored
}
return min; // return head.data that you assigned in the first line

这很破。

  1. 您忘记将 findmin(head.next, min) 的结果分配给 任何东西

  2. 即使 head.data

  3. 你忘了检查列表是否为空

  4. 初始值应为 int.MaxValue。不是 0,也不是 10000 上面建议。那么你不需要这个额外的比较(因为 任何东西都小于 100000)

  5. 最好把递归调用放在最后让编译器(或JIT) 用循环替换尾递归。或者自己写一个循环。

应该是这样的

public static int findMin(Node head,int min=int.MaxValue)
{
     if (head == null) return min;
     if (head.data < min) min = head.data;
     return findmin(head.next, min);
}

【讨论】:

  • 是否优化了 C# 尾调用?无论如何,这应该是公认的答案:P
  • 我以为是这样,但我错了。据此:stackoverflow.com/questions/7102520/… 编译器不会这样做,但 JIT 会优化这些调用。
  • 这行得通。我现在看到了我的实现中的基本缺陷。谢谢!
  • @yu_sha,在您的示例代码中,当 head.data 不小于 min 时会发生什么?在那种情况下,我认为 findmin 方法没有什么可返回的,所以有时这不是问题吗?
  • 最初 min 设置为 int.MaxValue 的默认参数值。如果列表为空,这就是返回的内容。如果列表不为空,则第一个元素将小于(或等于)int.MaxValue。
【解决方案2】:

findmin 的递归调用的响应永远不会分配给 min。所以像min = findmin(head.next, min); 这样称呼它应该可以解决你的问题

【讨论】:

  • 这不会解决问题,存在逻辑错误,一旦找到小于min 的值,递归就会停止。更不用说min 被初始化为零。
【解决方案3】:

一些问题: 1.按值传递min 2.min初始化为0

试试这个

public static int findMin(Node cur) {
    if (cur == null) return 1000000;
    int next_min = findMin(cur.next)
    if (cur.data < next_min) return cur.data;
    return next_min;
}

最好不要在这里使用递归来节省stack 内存。只需使用while 循环并找到最小值。

【讨论】:

    猜你喜欢
    • 2017-04-14
    • 2021-10-07
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2022-12-02
    相关资源
    最近更新 更多