(1)原因分析
第9行的递归不会陷入死循环,因为它们都会递归到if(l==r)的情形然后return返回。
(2)分析验证
下面给出了一个用于验证的递归二叉树图
l+r>>1
以上代码表示右移1位,注意是在二进制下的右移,那么值得注意的是,偶数右移一位相当于/2,而奇数右移一位相当于-1再/2(也就是/2再向下取整)。但C++里的整型变量/2会自动向下取整,也就是只取整数部分(原因是二进制数字右移一位,右边是‘1’还是‘0’对结果没有关系),例如:
以下数字均为2进制:
1111111110 >> 1 = 111111111(去掉右边的‘0’)
1111111111 >> 1 = 111111111(去掉右边的‘1’)
两者没有区别!
你这个数组是从0开始读入,也就是说a[0]是有值的,不会因为l+r=1,mid=0而取不到值。
mid=l+r>>1其实就是取中间值,是不会出问题的。
第9行一直调用,就是分别让l和mid、r和mid无限接近,以第一个为例,mid=(l+mid)>>1,是不断减小的,一直到mid=l+1时再调用,mid=(l+1+l)>>1,由于右移的性质(向下取整),mid就变为了l,这时,递归调用就结束了。
例如 正整数i , i>>n 表示正整数i 的二进制向右移n位,多出的高位补零,
>>的优先级低于 + 号,所以这个 l+ r>>1 的意思是 (l+r)/2 ,
建议不要搞这么花里胡哨的东西,除非是为了acm题和竞赛的,在项目中你同事看到了也有可能一脸问号.
这个算法实现是递归实现,要理解栈的原理才好理解递归.
在函数递归中编译器的翻译是在函数中调用函数时,会保存这个函数的栈环境,然后进入被调用的函数,再建立一个函数执行环境到栈中.直到函数结束运行后,按栈的先入先出的顺序释放栈空间. 所以说所有的递归实现都可以用栈数据结构重现,因为编译器翻译后就是用栈实现的.
这道题,第8行后就是执行下一个函数,进行递归,创建函数栈的空间和环境,所以在这里不断的分化下一个函数的归并范围, 取中点一分为二,直到长度为1 时,停止分化.然后执行函数内容,完成函数后,不断释放栈空间,回到上一个函数后,不断的归并 排序范围,直到归并到整个数组,完成递归
为什麽你会认为死循环呢?
mid = l+r >> 1;
和
mid = (l+r)/2;是一个意思啊。
说说为什么你会认为是死循环
l+r的值右移1位,相当l+r的值除以2取整。
mid=l+r>>1与mid=(l+r)/2相同,不会死循环
第九行的递归也不会死循环,他是有返回条件的