您的位置:首页 > 其它

递归再谈

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


这是一个归并排序,但很能说明递归的本质,运行结果

比较长,可以看出,递归相当栈一样,先进的后出,每次

出栈进行返回,即就是返回上一层
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: