递归
视频演示
什么是递归?
- 递归是一种非常高效、简洁的编码技巧,一种应用非常广泛的算法,比如DFS深度优先搜索、前中后序二叉树遍历等都是使用递归。
- 方法或函数调用自身的方式称为递归调用,调用称为递,返回称为归。
- 基本上,所有的递归问题都可以用递推公式来表示。
递归的优缺点
- 优点:代码的表达力很强,写起来简洁。
- 缺点:空间复杂度高、有堆栈溢出风险、存在重复计算、过多的函数调用会耗时较多等问题。
什么样的问题可以用递归解决呢?
一个问题只要同时满足以下3个条件,就可以用递归来解决:
- 1.问题的解可以分解为几个子问题的解。(子问题:数据规模更小的问题)
- 2.问题与子问题,除了数据规模不同,求解思路完全一样
- 3.存在递归终止条件
例题讲解
SDUT 1200 - 汉诺塔
代码:
#include<bits/stdc++.h>
using namespace std;
void hanno(int n,char A,char B,char C)
{
if(n==1)
printf("Move disk %d from %c to %c\n",n,A,C);
else
{
hanno(n-1,A,C,B);
printf("Move disk %d from %c to %c\n",n,A,C);
hanno(n-1,B,A,C);
}
}
int main()
{
int n;
cin>>n;
hanno(n,'A','B','C');
}
SDUT 3479 - 青蛙过河
代码:
#include<bits/stdc++.h>
using namespace std;
int pass(int s,int y)
{
if(s==0)
return y+1;
else
{
return 2*pass(s-1,y);
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
printf("%d\n",pass(n,m));
}
return 0;
}
SDUT 3491 - 数据结构实验之排序八:快速排序
代码:
#include<bits/stdc++.h>
using namespace std;
void qsort(int *a,int l,int r)
{
int i=l,j=r;
int k=a[l];
if(i>=j)
return ;
else
{
while(i<j)
{
while(i<j&&a[j]>=k) j--;
a[i]=a[j];
while(i<j&&a[i]<=k) i++;
a[j]=a[i];
}
a[i]=k;
qsort(a,l,i-1);
qsort(a,i+1,r);
}
}
int main()
{
int a[111111];
int n;
while(cin>>n)
{
int i;
for(i=1;i<=n;i++)
{
cin>>a[i];
}
qsort(a,1,n);
for(i=1;i<=n;i++)
{
if(i==n)
printf("%d\n",a[i]);
else
printf("%d ",a[i]);
}
}
return 0;
}
SDUT 2872 - M–二分查找
代码:
#include<bits/stdc++.h>
using namespace std;
int erfen(int *a,int l,int r,int k)
{
int mid=(l+r)/2;
while(l<=r)
{
if(a[mid]==k)
return mid;
else if(a[mid]>k)
return erfen(a,l,mid-1,k);
else if(a[mid]<k)
return erfen(a,mid+1,r,k);
}
return -1;
}
int a[3000010];
int main()
{
ios::sync_with_stdio(false);
int n;
int i,k;
cin>>n;
for(i=1; i<=n; i++)
{
cin>>a[i];
}
int q;
cin>>q;
while(q--)
{
cin>>k;
printf("%d\n",erfen(a,1,n,k));
}
return 0;
}
SDUT 4165 - 全排列问题
代码:
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
const int N = 1e5 + 10;
const int M = 111;
using namespace std;
int a[11];
///右移元素
void move_r(int l,int r){
if(l>=r) return ;
int t=a[r];
for(int i=r;i>l;i--) a[i]=a[i-1];
a[l]=t;
}
///左移元素
void move_l(int l,int r){
if(l>=r) return ;
int t=a[l];
for(int i=l;i<r;i++) a[i]=a[i+1];
a[r]=t;
}
///递归全排列
void perm(int l,int r){
if(l==r){
for(int i=1;i<=r;i++){
if(i==r) cout<<a[i]<<endl;
else cout<<a[i]<<",";
}
}
else{
for(int i=l;i<=r;i++){
swap(a[l],a[i]);
move_r(l+1,i);
perm(l+1,r);
move_l(l+1,i);
swap(a[l],a[i]);
}
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
perm(1,n);
return 0;
}