【问题标题】:reverse a linkedlist recursively递归地反转链表
【发布时间】:2016-06-11 06:29:59
【问题描述】:

我的链表反向函数给出了正确的结果。但我是
困惑。

linked list= 12->5->4->3

as per my reverse function the result should be
4->5->12

but fortunately it produces the correct reversed list
3->4->5->12.

pls help me to understand what happening 




//head_ref  global variable



struct n* reverse(struct n *head){

    struct n *pre,*cur;  //temp variable for first and second node

    if(head->next==NULL){
        head_ref = head;   // head_ref global variable initialized with head pointer
        return;
     }
    pre = head;
    cur = head->next;
    reverse(cur);

    cur->next = pre ;
    pre->next = NULL;

 }

第一次通话 前 = 12 电流 = 5 第二次通话 前 = 5 当前 = 4 第三次通话 前 = 4 cur = 3

   3->next = NULL //base condition fullfilled
   so it will exit ( 3rd call )

   reverse will start from 
   second call
      pre = 5
      cur = 4

我的反向链表应该是4->5->12

但它产生 3->4->5->12(正确的反向链表)

为什么它会给出正确的结果。请解释一下????

【问题讨论】:

    标签: c recursion linked-list


    【解决方案1】:

    让我们从链表12->5->4->3开始。 当您的 main(或其他调用函数)调用 reverse 函数时,head 有数据 12。以下是第四次调用 reverse 函数后创建的堆栈。

                     |                                           |
                     |___________________________________________|     gonna be
                     |__*head=3 *head->next=NULL__head_ref=3_____| => popped out
                     |__*head=4 pre=4 curr=3_____________________|   
                     |__*head=5 pre=5 cur=4______________________|
         main calls=>|__*head=12_pre=12 cur=5____________________| 
    

    如你所说,上图你已经很清楚了。当 head->next = NULL 时,堆栈中最顶部的条目被弹出,而具有 *head=4、pre=4 和 curr=3 的条目成为堆栈中的最顶部条目。然后 curr->prev 评估为 3->next=4 和 4->next->NULL。

                     |                                                      |
                     |                                                      |
        popped out=> |______________________________________________________|
                     |__*head=4 pre=4 curr=3__(3->next)=4__(4->next)=NULL___|
                     |__*head=5 pre=5 cur=4_________________________________|
                     |__*head=12_pre=12 cur=5_______________________________| 
    

    然后带有 *head=4 pre=4 curr=3__(3->next)=4__(4->next)=NULL 的条目会弹出,同样的事情也会发生。

                     |                                                      |
                     |                                                      |
                     |                                                      |
        popped out=> |______________________________________________________|
                     |__*head=5 pre=5 cur=4____(4->next)=5___(5->next=NULL)_|
                     |__*head=12_pre=12 cur=5_______________________________| 
    

    在剩下的一个条目中你可以看到 12->next 变成了 NULL,所以 12 现在变成了链表的尾部。

                     |                                                      |
                     |                                                      |
                     |                                                      |
                     |                                                      |
        popped out=> |______________________________________________________|
                     |__*head=12_pre=12 cur=5__(5->next)=12_(12->next)=NULL_| 
    
    
                     |                                                      |
                     |                                                      |
                     |                                                      |
                     |                                                      |
                     |                                                      |
        popped out=> |______________________________________________________| 
    

    堆栈变空,你的最终链表有 3 个作为头部,12 个作为尾部:3->4->5->12

    【讨论】:

      【解决方案2】:

      3->next = NULL //基本条件已满,所以它会退出(3rd 打电话)

      reverse 将从第二次调用开始 前 = 5 cur = 4

      这里没有反向开始

      调用 pre = 4 cur = 3

      你调用 reverse(3) 什么都不做, 然后你执行行

      cur->next = pre ;
      pre->next = NULL;
      

      其中 cur=3 和 pre = 4,所以你得到 3->4

      【讨论】:

      • 每个递归调用都会创建单独的范围。所以当 reverse(3) 被调用时,它会被返回。所以 reverse(3) 的范围将完成。并且 reverse(4) 的范围将生效。当时 cur 值为 4。
      • @raton 是的,在每次调用 reverse 时,您都有新的范围,但是您忘记了在 reverse(cur); 之后恢复了范围您有 pre = 4; cur = 3; reverse(3); 3->next = 4; 4->next = NULL; 什么不清楚?
      猜你喜欢
      • 2012-11-05
      • 2020-10-02
      • 1970-01-01
      • 2010-09-26
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多