【问题标题】:Recursive MergeSort translation from C to C#从 C 到 C# 的递归 MergeSort 翻译
【发布时间】:2017-11-22 04:36:20
【问题描述】:

由于 .NET 要求所有变量在使用之前必须先实例化,我完全被合并排序的递归实现所困扰。我的教授希望我们使用递归算法将 MergeSort 的 C 代码翻译成 C#。这是C代码:

void doMergeSort(contact **head)
{
    // do not process empty or single-node list
    if (head==NULL || *head == NULL || (*head)->next==NULL)
        return;

    contact *first, *second;

    // split the list in half
    splitList(*head, &first, &second);

    // perform recursive merge sort on both halves
    doMergeSort(&first);
    doMergeSort(&second);

    // Merge both halves back together,
    mergeList(first, second)
}

这是我的实现:

public static void DoMergeSort(ref LinkNode<T> head)
{
    if (head == null || head.Next == null)
        return;

    LinkNode<T> first = null, second = null;

    SplitList(head, ref first, ref second);

    DoMergeSort(ref first);
    DoMergeSort(ref second);

    head = MergeLists(first, second);
}

现在,由于 C#/.NET 的规则,我不能省略第一个和第二个实例化,但是在函数中将它们声明为 null 会破坏它的递归性质。我已经被这个问题困扰了好几天了,我的教授也帮不上什么忙。尝试将其转换为迭代函数会更好吗,还是有一种方法可以递归完成?

我对采用迭代方法的唯一担心是它会“破坏”分配的规则。

【问题讨论】:

  • 如果这是一个编程练习,请继续……否则只需使用众多内置函数之一进行排序。即 List.Sort 或 linq OrderBy
  • 另外,我建议在处理不确定的递归深度时不要使用递归算法。根据深度,您可以轻松地用完堆栈。 .NET 应用程序中的默认堆栈大小仅为 1MB。例如,如果每次递归占用 100 个字节,则最大可能的迭代次数将是
  • 我不知道你的问题是什么,但你的诊断不可能是正确的。为变量即将被覆盖赋予初始值不可能“搞砸递归性质”,无论这意味着什么。还有其他问题,无论是什么问题,都存在于您忽略向我们展示的代码中。
  • "现在,由于 C#/.NET 的规则,我不能省略实例化第一个和第二个":如果您不想在通过 ref 传递变量之前初始化变量,请使用out 关键字而不是 ref 关键字。

标签: c# .net sorting mergesort


【解决方案1】:

我可能遗漏了一些关于 C# 的内容,但设置 first 和 second = null 应该不是问题,因为 SplitList(...) 应该将列表从 head(不是 null)分成两半,第一一半进入左边,下半场进入第二个。然后递归发生在现在非空的 first 和 second 列表中,并且每个递归级别都会创建另一对 first 和 second。

代码与 C 代码不完全一致,您需要检查列表是否只有一个节点(C 代码检查 (*head)->next == NULL 来执行此操作)。如果只有一个节点,该函数应该只是返回。

虽然不是你的课堂作业的一部分,但有一个迭代版本的链表合并排序。它使用一个小的(26 到 32)内部列表数组。它比递归版本更快,因为它不必扫描子列表来拆分它们。 Wiki 文章对此进行了描述。

https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists

【讨论】:

  • 太好了,感谢您的帮助!我已经盯着这个看了这么久,以至于在我的脑海中这个方法中递归的工作方式真的搞砸了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 2019-10-07
  • 2013-06-30
  • 1970-01-01
相关资源
最近更新 更多