算法向|递归---成功的说客

算法中,最简单但是又让人理解起来比较困难的算法就是递归了。

 

今天IT圈圈给你分享下怎么理解它:

 

 

 

先听我讲个老故事

 

 

 

一位优秀的商人杰克,有一天告诉他的儿子... 
   杰克:我已经决定好了一个女孩子,我要你娶她。 
   儿子:我自己要娶的新娘,我自己会决定。 
   杰克:但我说的这女孩,可是比尔盖茨的女儿喔! 
   儿子:哇!那这样的话... 
   在一个聚会中,杰克走向比尔盖茨... 
   杰克:我来帮你女儿介绍个好丈夫。 
   比尔:我女儿还没想嫁人呢! 
   杰克:但我说的这年轻人,可是世界银行的副总裁喔! 
   比尔:哇!那这样的话... 
   接著,杰克去见世界银行的总裁。 
   杰克:我想介绍一位年轻人来当贵行的副总裁。 
   总裁:我们已经有很多位副总裁,够多了! 
   杰克:但我说的这年轻人,可是比尔盖茨的女婿喔! 
   总裁:哇!那这样的话... 

 

 

 

悟出道理

 

 

 

这个故事告诉我们一个道理,我可以先假设一个事情,再这个假设基础上,我们做接下来的事情。

 

用到算法上,我们先假设后面的递归调用已经帮我们做好了,我们写接下来的的事情。

 

这个假设就是递归的精髓。

 

而递归其实真的是一个成功的说客。

 

 

 

反转一个链表

 

 

现在我们用递归实现:反转一个单向链表。

 

 

 

reverse_ll(struct node ** hasHref)

{

    struct node * first,last;

    if(hasHerf ==null) return -1;

    first = * hasHref;//伪装成第一个

    rest = first->next;

    if(rest == null) return ;//后面没有了,退出

    reverse_ll(&rest);//说客在这里,从第二个元素开始,“假装(递归)”这个元素的右边部分已经被反转,然后在“假装”的基础上,交换左边和右边

    first->next->next =first;

    firest->next = null;

|

 

以此类推,每个函数调用都要假装,直到假装不下去了,还剩最后一个的时候返回。

 

示意图

 

  1. 刚开是链表是这样的

  2. 然后从第二个开始"假装"如下:234“已经”被反转,然后交换

     

  3. 现在列表“实际”如下

     

     

  4. 然后2伪装成第一个,重复过程:从3开始"假装"如下:34“已经”被反转完成,然后交换

  5. 然后3伪装成第一个,4开始伪装右边已好,虽然他右边没有了

  6. 然后4伪装成第一个,发现没有rest了,退出

 

总结

 

这里注意,函数的执行顺序和我们的图解正好是反的,所以我们可以把伪装成第一个的下一个设为null,firest->next = null,为后面函数返回后指向后面的腾出空间。

 

喜欢IT圈圈的文章,请长按关注下吧

 

posted @ 2017-08-15 11:11  IT圈圈  阅读(174)  评论(0编辑  收藏  举报

皮皮虾美剧