【问题标题】:how does this recursive function work? to merge sort two singly linked lists这个递归函数是如何工作的?合并排序两个单链表
【发布时间】:2019-05-28 17:18:48
【问题描述】:

我在 geeksforgeeks.org 上的 C++ 中找到了这个递归函数,用于合并和排序两个单链表,我使用 netbeans 调试了这段代码,但我仍然无法清楚地了解这段代码背后的功能。我也看到过类似的代码stackoverflow,但没有解释它的工作方式。我的问题是关于它背后的想法以及它的工作方式,这里的充分解释也将帮助其他人解决同样的问题。

在netbeans上调试代码,了解代码的工作流程

//Merges two given lists in-place. This function 
// mainly compares head nodes and calls mergeUtil() 

Node *merge(Node *h1, Node *h2) 
 { 
if (!h1) 
    return h2; 
if (!h2) 
    return h1; 

// start with the linked list 
// whose head data is the least 
if (h1->data < h2->data) 
{ 
    h1->next = merge(h1->next, h2); 
    return h1; 
} 
else
{ 
    h2->next = merge(h1, h2->next); 
    return h2; 
 } 
} 

这个函数应该返回一个排序的链表

【问题讨论】:

  • 对“归纳证明”做一些谷歌搜索。这是一个数学概念,但它完美地应用在这里。一旦你阅读并理解了归纳证明的工作原理,你应该能够完美地理解这个递归函数:假设这个函数返回一个排序列表。那是你的出发点。此函数返回一个排序列表。你接受这个事实,理所当然。现在,使用您刚刚学习的归纳证明的基本原理,逐行完成这个简单的函数。
  • 链接 Mathematical inductionStructural induction 会很有帮助

标签: c++ function sorting recursion singly-linked-list


【解决方案1】:

我相信举个例子是理解递归算法如何工作的最佳方式。让我们以这两个示例链表为例:

  • {13, 24, 74}
  • {34, 72, 95}

请注意,它们都已排序,因为这是 algorithm 的要求:

给定两个排序列表,将它们合并以产生一个组合排序列表

我已经对结果进行了跟踪:

  • 箭头是执行顺序
  • 每一行都是一个堆栈帧。特别是,左边的行是在递归调用merge 之前,右边是它之后的结果。

还要注意以下几点:

  • 在左侧的每个箭头上,从节点开始的较小元素消失
  • 在返回的路上,较小的元素在另一边获得元素的排序顺序。最后我们以排序的形式返回刚刚获得另一个的列表,即:{13, 24, 34, 72, 74, 95}

【讨论】:

    【解决方案2】:

    我在代码中添加了 cmets。我还将 if 从 data == h2->data,则首先需要 h1 以保持稳定性。请记住,这两个列表已经排序,这个函数只是合并它们。

    函数递归地跟随两个列表,跳过较小的节点,直到到达其中一个列表的末尾,此时它将该列表的末尾设置为另一个列表的其余部分,然后返回返回递归调用链,沿着列表向后工作,设置较小的节点下一个指针以从后到前合并列表。这是一种合并列表的低效方式,因为每个节点上的递归都会消耗 O(n) 堆栈空间,但它可能是一种学习练习,而不是高效。

    // initial input parameters, h1 and h2 each point to already sorted lists
    Node *merge(Node *h1, Node *h2) 
    {
        if (!h1)                                // if h1 empty
            return h2;                          //  return h2
        if (!h2)                                // if h2 empty
            return h1;                          //  return h1
    
        if (h1->data <= h2->data)               // if h1->data <= h2->data
        {
            h1->next = merge(h1->next, h2);     //  h1->next = smaller of {h1->next, h2}
            return h1;                          //  return h1
        }
        else                                    // else h1->data > h2->data
        {
            h2->next = merge(h1, h2->next);     //  h2->next = smaller of {h1, h2->next}
            return h2;                          //  return h2
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-04
      • 1970-01-01
      • 2015-12-30
      • 2021-09-27
      • 2019-09-09
      • 2021-07-27
      • 2017-08-23
      • 2016-11-01
      • 2011-03-29
      相关资源
      最近更新 更多