更好地了解链表中的递归

时间:2019-07-15 18:34:10

标签: list recursion linked-list pascal

我想更深入地了解递归,而不仅仅是凭直觉。我知道这个概念,也知道如何递归求解阶乘或斐波那契数列。但是我似乎无法很好地形象地了解递归使用时链表中到底发生了什么。

更具体地说,我正在努力理解以下算法:

(它在链接列表中寻找最大值。它通过从第二个元素开始递归搜索最大值来进行。然后将其与第一个元素进行比较,并返回较高的一个。)

 function MaxRec (inRefBegin : tRefList) : tRefList;
  { returns recursively a pointer to the max element in a list }

    var
    rekMax : tRefList; { variable to point to the recursive maximum 
                          starting from second element }
    begin
      if inRefBegin = nil then { Base Case, recursion stops }
        MaxRec := nil
      else
      begin
        rekMax := MaxRec (inRefBegin^.next); 
        if rekMax = nil then
          MaxRec := inRefBegin
        else
          if inRefBegin^.info < rekMax^.info then
            MaxRec := rekMax
          else
            MaxRec := inRefBegin
      end { if }
    end; { MaxRec }


我确实了解理论上会发生什么。我很难一步一步地看到它。在每个堆栈级别会发生什么? 我没有得到的是这行代码如何:rekMax := MaxRec (inRefBegin^.next)可以找到最大值...。它仅使用指向下一项的指针来调用该函数,而没有比较任何值。每次调用该函数时都要进行比较??

我的思考过程是这样的: 假设我有一个像这样的链表:

5 => 7 => 10 => 3 => 2 => nil 
  1. 函数被调用并且不是nil((保存到堆栈))
  2. 函数被调用并且不是nil((保存到堆栈))
  3. 函数被调用并且不是nil((保存到堆栈))
  4. 函数被调用并且不是nil((保存到堆栈))
  5. 函数被调用并且不是nil((保存到堆栈))
  6. 递归停止

  7. 现在会发生什么?是否在每个函数中都与第一个元素进行比较?还是这是我已经拥有递归最大值的地方? s.o可以看到吗?

我非常感谢您的帮助。我知道该主题在线上有大量资源,相信我已经阅读了。但是我仍然不清楚每个级别上到底发生了什么。

1 个答案:

答案 0 :(得分:1)

  
    

7)现在会发生什么?是否在每个函数中都与第一个元素进行比较?还是这是我已经拥有递归最大值的地方? s.o可以看到吗?

  

在7)递归停止,因为您已经到达列表的末尾,因此返回nil。 然后,您继续上一个调用,其中MaxRec的结果现在为nil,因此最后一部分的最大值为当前的inRefBegin值(再次,因为返回了nil)。

对于其他级别,退出递归,将当前节点中的值与递归调用返回的值进行比较,并保留最大的值,直到最后剩下最大的节点用于整个列表。

有帮助吗?