递归再谈

#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

这是一个归并排序,但很能说明递归的本质,运行结果
比较长,可以看出,递归相当栈一样,先进的后出,每次
出栈进行返回,即就是返回上一层

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值