递归再谈
2016-07-18 12:14
288 查看
#include<stdio.h> void up_and_down(int); int main(void) { up_and_down(1); return 0; } void up_and_down(int n) { printf("time %d:n location %p/n",n,&n);//1 printf("\n"); if(n<4) up_and_down(n+1); printf("\n"); printf("time %d:n location %p/n",n,&n); //2 } time 1:n location 0018FEF8/n time 2:n location 0018FEA0/n time 3:n location 0018FE48/n time 4:n location 0018FDF0/n time 4:n location 0018FDF0/n time 3:n location 0018FE48/n time 2:n location 0018FEA0/n time 1:n location 0018FEF8/nPress any key to continue
首先, main() 使用参数 1 调用了函数 up_and_down() ,于是 up_and_down() 中形式参数 n 的值是 1, 故打印语句 #1 输出了 time 1
然后,由于 n 的数值小于 4 ,所以 up_and_down() (第 1 级)使用参数 n+1 即数值 2 调用了 up_and_down()( 第 2 级 ). 使得 n 在第 2
级调用中被赋值 2, 打印语句 输出的是 time 2 。与之类似,下面的两次调用分别打印出 time 3 和 time 4。
当开始执行第 4 级调用时, n 的值是 4 ,因此 if 语句的条件不满足。这时候不再继续调用 up_and_down() 函数。第 4 级调用接
着执行打印语句 #2 ,即输出 time 4,因为 n 的值是 4 。现在函数需要执行 return 语句,此时第 4 级调用结束,把控制权返回给该
函数的调用函数,也就是第 3 级调用函数。第 3 级调用函数中前一个执行过的语句是在 if 语句中进行第 4 级调用。因此,它继
续执行其后继代码,即执行打印语句 #2 ,这将会输出 time 3 .当第 3 级调用结束后,第 2 级调用函数开始继续执行,即输出
time 2 .依次类推.
注意,每一级的递归都使用它自己的私有的变量 n .可以查看地址的值来证明.
递归的基本原理:
1 每一次函数调用都会有一次返回.当程序流执行到某一级递归的结尾处时,它会转移到前一级递归继续执行.
2 递归函数中,位于递归调用前的语句和各级被调函数具有相同的顺序.如打印语句 #1 位于递归调用语句前,它按照递
归调用的顺序被执行了 4 次.
3 每一级的函数调用都有自己的私有变量.
4 递归函数中,位于递归调用语句后的语句的执行顺序和各个被调用函数的顺序相反.
5 虽然每一级递归有自己的变量,但是函数代码并不会得到复制.
6 递归函数中必须包含可以终止递归调用的语句.
#include<iostream> #include<string.h> #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define len 10 void Show(int str[],int length); void mergerarray(int str[],int left,int mid,int right,int temp[]); void Merger_sort(int str[],int length); void merger_sort(int str[],int left,int right,int temp[]); using namespace std; void Show(int str[],int length) { int i; for(i = 0;i <length ;i++) { printf(" %d",str[i]); } } void mergerarray(int str[],int left,int mid,int right,int temp[]) { printf("合并数组:str = %p ,left = %d,mid = %d,right = %d\n",str,left,mid,right); int i = left; int j = mid + 1; int m = mid; int n = right; int k = 0; while(i <= m && j <= n) { if(str[i] < str[j]){ temp[k] = str[i]; k++; i++; }else{ temp[k] = str[j]; k++; j++; } } while( i < m ) { temp[k] = str[i]; k++; i++; } while( j < n){ temp[k] = str[j]; k++; j++; } for( i = 0 ;i< k; i++) { str[left + i] = temp[i]; } } void merger_sort(int str[],int left,int right,int temp[]) { if(left < right) { int mid = (left + right)/2; printf("str %p,left= %d,mid = %d,right = %d \n",str,left,mid,right); merger_sort(str,left,mid,temp); merger_sort(str,mid+1,right,temp); printf("递归调用结束str %p,left= %d,mid = %d,right = %d \n",str,left,mid,right); printf("\n"); mergerarray(str,left,mid,right,temp); } } void Merger_sort(int str[],int length) { int *temp_array = (int *)malloc((sizeof(int )*length)); int * p = temp_array; if( p = NULL) { return ; } merger_sort(str,0,length - 1,temp_array); } int main() { int str[len]; int i ; for(i = 0; i < len; i++) { str[i] = rand()%100; } printf("排序前:\n"); Show(str,len); printf("\n"); printf("排序后:\n"); Merger_sort(str,len); Show(str,len); return 0; } 运行结果: 排序前: 41 67 34 0 69 24 78 58 62 64 排序后: str 0018FF20,left= 0,mid = 4,right = 9 str 0018FF20,left= 0,mid = 2,right = 4 str 0018FF20,left= 0,mid = 1,right = 2 str 0018FF20,left= 0,mid = 0,right = 1 递归调用结束str 0018FF20,left= 0,mid = 0,right = 1 合并数组:str = 0018FF20 ,left = 0,mid = 0,right = 1 递归调用结束str 0018FF20,left= 0,mid = 1,right = 2 合并数组:str = 0018FF20 ,left = 0,mid = 1,right = 2 str 0018FF20,left= 3,mid = 3,right = 4 递归调用结束str 0018FF20,left= 3,mid = 3,right = 4 合并数组:str = 0018FF20 ,left = 3,mid = 3,right = 4 递归调用结束str 0018FF20,left= 0,mid = 2,right = 4 合并数组:str = 0018FF20 ,left = 0,mid = 2,right = 4 str 0018FF20,left= 5,mid = 7,right = 9 str 0018FF20,left= 5,mid = 6,right = 7 str 0018FF20,left= 5,mid = 5,right = 6 递归调用结束str 0018FF20,left= 5,mid = 5,right = 6 合并数组:str = 0018FF20 ,left = 5,mid = 5,right = 6 递归调用结束str 0018FF20,left= 5,mid = 6,right = 7 合并数组:str = 0018FF20 ,left = 5,mid = 6,right = 7 str 0018FF20,left= 8,mid = 8,right = 9 递归调用结束str 0018FF20,left= 8,mid = 8,right = 9 合并数组:str = 0018FF20 ,left = 8,mid = 8,right = 9 递归调用结束str 0018FF20,left= 5,mid = 7,right = 9 合并数组:str = 0018FF20 ,left = 5,mid = 7,right = 9 递归调用结束str 0018FF20,left= 0,mid = 4,right = 9 合并数组:str = 0018FF20 ,left = 0,mid = 4,right = 9 0 24 34 41 34 58 58 62 64 64 Press any key to continue
这是一个归并排序,但很能说明递归的本质,运行结果
比较长,可以看出,递归相当栈一样,先进的后出,每次
出栈进行返回,即就是返回上一层
相关文章推荐
- Bootstrap表单
- 百度地图导航功能 希望对大家有用吧
- 大话行车记录器产品系统设计 - 基于芯片商提供的SDK API开发之三
- 使用matplotlib库绘图出现的问题
- 记录小白前端成长02
- Python——4Dict和Set类型
- 改变image的尺寸大小,按原比例不拉伸。
- 视图旋转 AVPlayer视频播放视图旋转
- NPOI操作excel异常
- using libnet to send igmp join packet.
- 算法实战(三)--求K-Pairs
- mybatis-generator-core生成代码
- 清除微信浏览器缓存 禁用浏览器缓存
- 备份数据库
- Codeforces Round #309 (Div. 2) D 构造
- GStreamer详解1 hello world
- 2-SAT
- 【刷题之路】二叉树中和为某一值的路径
- AndroidStudio安装与Genymotion模拟器
- JsonObject 解析 json