天勤考研数据结构2019高分笔记P124
先上代码:
float findmax(float A[],int i,int j){ float max=0; if(i==j){ return A[j]; }else{ printf("递归前:"); printf("i指针 :%d ",i);printf("A[i]值:%f ",A[i]); printf("最大值:%f ",max); max=findmax(A,i+1,j); printf("递归后:"); printf("i指针 :%d ",i);printf("A[i]值:%f ",A[i]); printf("最大值:%f ",max); if(A[i]>max){ return A[i]; }else{ return max; } } } int main() { float a[]={2,4,2,3,1}; float max=findmax(a,0,4); printf("%f",max); return 0; }
书上的讲解:1,如果数组为长度为1,直接返回最大值
2,将数组视为俩部分A【0】,A【1,,,n-1】,如果A【0】大于A【1,,,n-1】的最大值,返回A【0】,反之递归处理A【1】和A【2,,,n-1】;
根据书上讲的,是按数组索引从头到尾比较的。但其实质是从尾到头的顺序来比较的。
max最先是i=j=5时被赋值为1 然后是3,然后是和a【2】(2)比较3,然后是3和a[1]比较为4,最终4和 a[0] (2)比较为4 (其实是4.0)
(向下递归,只执行递归前的代码,即只判断i和j是否相等,当这一级递归执行到结尾处时,它会转移到前一级递归继续执行,即转移到findmax(1,4,5)处),然后继续向上转移
打印结果:(递归前的意思是向下递归还没达到递归结尾)
可能有些小伙伴好奇findmax(1,5,5)怎么转移到findmax(1,4,5),所以我再讲一下:
递归调用的内部执行过程:
a,运行开始时,首先为递归调用建立一个工作栈,其结构包括值参,局部变量,返回地址。
b,每次执行递归调用之前,把递归函数的值参和局部变量的当前值以及调用的返回地址压栈
c,每次递归调用之后,将栈顶元素出栈,使相应的值参和局部变量恢复为调用前的值,然后转向返回地址指定的位置继续执行。
画个图说明一下:假设有一块这样的地址:
需要注意下函数的代码并不会复制, findmax(a,5,5)和findmax(a,4,5)用的是同一个函数,即对应同一块地址(图中的这里是递归的函数代码,代码经过汇编转换为字节码)。