• 西山居递归面试题


    一道西山居的面试题,求好的解题思路?

    #include<iostream>
    
    int cc(int i)
    {
        for(;i<4;)
        {
            std::cout<<cc(++i);
        } 
        return i; 
    }
    
    int main()
    {
        cc(1); 
        return 0;
    } 
    

    输出结果:___ ?

    题目来自:https://www.zhihu.com/question/50552768


    解决方案:

    这道题困扰了我很久,看了很多相关递归的书,之前一位大神朋友告诉我递归很重要,他是分而治之和动态规划的基础,我也没系统学过递归树的画法。

    看了一段时间以后,我也跟着画了一个递归函数调用树,起初不能理解递归树,其实主要遗落了:cout cc(2)的右子树,每一步都单独来看,由于自己实在太笨了,就不得不改写了一下源程序:

    int cc(int i)
    {
    	//cout << "call cc(" << i << ")" << endl;
    	for (; i<4;)
    	{
    		++i;
    		std::cout << cc(i) << endl;
    	}
    	return i;
    }
    

    参考书(《面向算法设计的数据结构C++语言版》)中p75提到的:

    递归中每个函数实体是相互独立的存在,即便它们参数完全一致,也不例外。
    递归的唯一体现仅在于递归函数共用一段静态的程序代码,若为每个函数分别保存数据以记录它执行到程序代码的哪一步,并保证各个函数的局部数据与其他函数无关,
    则可实现函数之间的独立性。而上述只与具体函数执行有关的信息称为其上下文。执行中的函数是动态的概念,它类似于操作系统中的进程,不妨为函数执行建立
    "函数进程"模型。函数进程存在新生(被其他函数调用而创建),运行(执行非函数调用的代码),等待(调用其他函数而自身暂停)和终止(运行结束)四种状态。(这里略去了就绪状态,
    一旦调用函数终止,调用者将直接从等待状态转为运行状态),很容易通过改变上下文达到切换函数进程的目的。对于递归来说,不失真的调用自己,而是创建一个
    与自身拥有共同代码但包含独立上下文的函数进程。

    慢慢来分析此程序:
    其实重点是i是在函数内进行加1操作的,也就是当i为3的时候,执行i加1以后,i变为4,要执行cout << cc(4) << endl;


    这是我画的递归调用树


    至此这道题终于完结了,有空改一下题,可以通过返回值变换下题型。平时没事的时候也拿出来锻炼一下。

    知乎上的答案:


    我来贡献一个比轮子哥好看的调用树<(╯3╰)

    作者:Theodore
    链接:https://www.zhihu.com/question/50552768/answer/121498074
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


    reference:
    《面向算法设计的数据结构C++语言版》谢勰 2015年第1版
    《数据结构C++语言版》第3版,邓俊辉
    《数据结构》(类C语言版)严蔚敏,吴伟民
    《数据结构与算法分析C语言描述》英文版
    《算法导论》原书第三版中文版

    转载本Blog文章请注明出处,否则,本作者保留追究其法律责任的权利。 本人转载别人或者copy别人的博客内容的部分,会尽量附上原文出处,仅供学习交流之用,如有侵权,联系立删。
  • 相关阅读:
    docker 加速器配置目录
    php 超时设置笔记
    php socket通过smtp发送邮件(纯文本、HTML,多收件人,多抄送,多密送)
    fabric 安装
    centos7下使用yum安装pip
    【转】linux tar 压缩
    ASP.NET MVC 5 默认模板的JS和CSS 是怎么加载的?
    NHibernate with ASP.NET MVC 入门示例
    Ajax入门
    NHibernate入门
  • 原文地址:https://www.cnblogs.com/drfxiaoliuzi/p/9261969.html
Copyright © 2020-2023  润新知