递归的实现(小案例)以及递归的优缺点的总结 斐波那契数列 汉诺塔问题 0-9全排列

递归是什么

递归可以实现分治这种算法,就是把一个复杂的大问题,分解成若干个相同的小分问题,直到问题全部解决。

递归案例

斐波那契数列

#include

int get_fibonacci(int number)
{
    //第一个和第二个斐波那契数列值为1
    if( 1==number || 2==number )
    {   
        return 1;
    }   
    //第三项开始的斐波那契数列是前2项的和
    else
    {   
        return get_fibonacci(number-1)+get_fibonacci(number-2);
    }   
}

int main()
{
    int n=0;
    printf("请输入要查找的第n个斐波那契数列的值:");
    scanf("%d",&n);
    printf("%d",get_fibonacci(n));
    return 0;
}

汉诺塔问题

递归的实现(小案例)以及递归的优缺点的总结 斐波那契数列 汉诺塔问题 0-9全排列_第1张图片
递归的实现(小案例)以及递归的优缺点的总结 斐波那契数列 汉诺塔问题 0-9全排列_第2张图片
首先递归要判断最后一步的情况(就是退出函数的条件)最后一块叠上去就行了 x->y(如下图)
递归的实现(小案例)以及递归的优缺点的总结 斐波那契数列 汉诺塔问题 0-9全排列_第3张图片
然后判断别的情况(前面的步骤)
将x上面的n-1个盘子通过z放到y上去
这时x只剩下一个盘子将盘子移到z上去
然后将n-1个盘子用递归的方法从y->z移过去就行了
递归的实现(小案例)以及递归的优缺点的总结 斐波那契数列 汉诺塔问题 0-9全排列_第4张图片

/*1、使用递归模拟汉诺塔的移动过程。*/
#include

void move(char x,char y,char z,int number)
{
    if(number==1)//最后一个盘子直接叠上去就行了
    {   
        printf("%c->%c\n",x,z);//最后一步将x上的最后一个盘子放到z上
        return;
    }   
    else
    {   
        move(x,z,y,number-1);//通过z将n-1个盘子从x到y
        printf("%c->%c\n",x,z);
        move(y,x,z,number-1);//最后通过x将n-1个盘子从y到z
    }   
}

int main()
{
    int len=0;
    char x='x',y='y',z='z';
    printf("请输入汉诺塔的层数:");
    scanf("%d",&len);
    move(x,y,z,len);
    return 0;
}

0-9全排序

思路和汉诺塔一样选取元素进行交换位置从第一个元素开始,和后面的依次交换,交换完成一次要用递归对后面的元素也进行排序,如果头元素到最后了就输出序列即可,拍完一趟之后要对元素进行归位,方便下面的元素进行排序。

/*2、全排列0~9。*/
#include

void sort(int head,int last,int arr[])
{
	if(head==last)//如果元素到了最后输出序列即可
	{
		for(int j=0;j<=last;j++)
		{
			printf("%d",arr[j]);
		}
		printf("\n");
	}
	//不是最后就要算出后面的数的排序
	else
	{
		//对后面的数进行排序
		for(int i=head;i<=last;i++)
		{
			//这里交换完成后拍完序后要进行还原
			int temp=arr[i];
			arr[i]=arr[head];
			arr[head]=temp;
			sort(head+1,last,arr);
			temp=arr[i];
			arr[i]=arr[head];
			arr[head]=temp;
		}
	}
}

int main()
{
	int arr[10]={0,1,2,3,4,5,6,7,8,9};
	sort(0,9,arr);
	return 0;
}

递归的特点

递归函数每调用一次都会在栈内存产生一份自己的拷贝,直到达到出口,才一层释放,因此使用递归非常耗费内存,与循环相比速度非常慢。
建议:能用循环解决的问题不要使用递归。
比如斐波那契数列用循环可以很快的得到结果,虽然看上去我们求几项时间差不多,但是当基数变大到一定的程度,时间的差将会是令人吃惊的

递归优点:
1. 简洁
2. 容易理解思路清晰
3. 可以解决非线性的执行过程。
缺点:
1.递归由于是函数调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址以及临时变量,而往栈中压入数据和弹出数据都需要时间
2.递归中很多计算都是重复的,由于其本质是把一个问题分解成两个或者多个小问题,多个小问题存在相互重叠的部分,则存在重复计算,如fibonacci斐波那契数列的递归实现
3.调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出
总结为
1、耗费内存、速度慢

优缺点的总结参考自博客:https://blog.csdn.net/wangzhenling/article/details/59702845

如有错误欢迎指出谢谢!!

你可能感兴趣的:(C基础知识,c语言)