C++递归算法经典实例详解

C++手札 专栏收录该内容
14 篇文章 0 订阅
/*--------------------------- 该段为引用-----------
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。

 ------------------------------------------------- */


说一下我对递归算法的理解。

递归算法的代码,可以分成两个部分:递归出口(满足输出条件之类的)和递归部分(递归代码的主体)。

递归算法特点之一就是把整体换成部分。比如阶乘和全排列问题,都是把问题“降阶”(待会看代码就知道什么意思了。)

还有一个最重要的特点————————效率低,但是递归算法作为入门级算法还是很值得我这样的小白研究的。


来看看几个经典的问题。1.全排列 ,2.汉诺塔,3.阶乘



1.全排列:给你一个数组,你把这个数组里的数的所有排列方式写列出来。

input {1,2,3}

output{1,2,3},{1,3,2},{2,3,1}......(懒得敲了)


代码:

#include <iostream>   
using namespace std;  
int n = 0;  
  
void swap(char *q ,char *p)  
{   //交换函数 
    int temp;  
    temp= *q;  
    *q = *p;  
    *p = temp;  
}   
   
void perm(char arr[],int k, int m )  
{  
    int i;  
    if(k >m)  
    {  
        for(i = 0 ; i <= m ; i++)  
        {  //递归结束出口,当数列只剩下一个数的时候输出 
            cout<<arr[i]<<" ";  
               
        }  
        cout<<endl;   
    }  
    else  
    {  
        for(i = k ; i <=m;i++)  
        {  //递归部分 
            swap(arr[k],arr[i]);  
            perm(arr,k+1,m);  
            /*把数组看成1{234}+2{134}+3{124}+4{123}
			再把{234}看成2{34}+3{24}+4{23}
			一直把整体化为部分,一直把大问题分解成小问题。*/ 
            swap(arr[k],arr[i]);  
        }  
    }  
}  
  
int main()  
{  
    char arr[] ="1234";  
    perm(arr,0,3);     
    return 0;  
}

2.汉诺塔问题

就是移环子的游戏


这个也可以用递归算法实现。

ABC分别是123柱子,代码思路大概是这样的

把N-1层的环子先通过C移到B,最后再把第N层的最大的环子移到C,这个时候就剩下一个N-1层的新“塔”,那么我们把他看成一个新的“塔”把B柱看成之前的A柱,通过C柱把(N-1)-1层移到A柱,再把第N-1层的最大(原本第二大)的环子放到C,如此循环最后N=1 就了解了。

#include<iostream>
using namespace std;
void hanoi(int n,char a,char b,char c)
{
if(n==1)
cout<<n<<" "<<a<<" "<<c<<endl;
else
{
hanoi(n-1,a,c,b);
cout<<n<<" "<<a<<" "<<c<<endl;
hanoi(n-1,b,a,c);
}
}
int main()
{
int n;
cout<<"输入正整数:"<<endl;
cin>>n;
cout<<"结果为"<<endl;
hanoi(n,'A','B','C');
/*
假设有4层,跟全排列差不多的想法,先把他看成3层,再看成2层,而且移动的方法是相同的。*/ 
return 0;
} 
3.阶乘……不讲了。。

  • 10
    点赞
  • 5
    评论
  • 36
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值