一、递归
1、递归的概念
直接或间接的调用自身的算法称为递归算法。
用函数自身给出定义的函数称为递归函数。
二要素:边界条件和递归方程
1.1阶乘函数
当n=0,n!=1;
当n>0,n!=n*(n-1)!
#include<iostream>
using namespace std;
int factorial(int n)
{
if(n==0) return 1; /*边界条件*/
else return n*factorial(n-1); /*递归方程*/
}
int main() /*以下算法调用过程类似,不再给出*/
{
int result;
int n;
while(cin>>n)
{
result = factorial(n);
cout<<result<<endl;
}
return 0;
}
1.2 Fibonacci 数列
当n=0||n=1,F(n)=1;
当n>=2,F(n)=F(n-1)+F(n-2)
int Fibonacci(int n)
{
if(n<=1) return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
1.3 排列问题–全排列
设·R={r1,r2,r3,…,rm}为要进行全排列的m个元素,Perm(R)为集合R的全排列,(ri)Perm(Ri)表示全排列Perm(Ri)的每一个排列加上前缀ri的排列。
当m=1,Perm(R)=(r);
当m>1,Perm(R)由(r1)Perm(R1)、(r2)Perm(R2)、…、(rn)Perm(Rn)组成。
m为数组长度减1,k初始值为0
void perm(int list[],int k,int m)
{
int i;
int t;
if(k==m)
{
for(i=0;i<=m;i++)
{
cout<<list[i]<<" ";
}
cout<<endl;
}
else
{
for(i=k;i<=m;i++)
{
t=list[k];list[k]=list[i];list[i]=t;
/*swap(list[k],list[i]);*/
perm(list,k+1,m);
/*swap(list[k],list[i]);*/
t=list[k];list[k]=list[i];list[i]=t;
}
}
}
1.4 整数划分
将正整数n表示为一系列正整数之和,称为正整数的划分。
q(n,m)表示最大加数n不大于m的划分个数。
①当m=1||n=1时,q(n,1)=q(1,m)=1;
②当n<m时,q(n,m)=q(n,n);
③当n=m时,q(n,n)=1+q(n,n-1);
④当n>m>1时,q(n,m)=q(n,m-1)+q(n-m,m);
int q(int n,int m)
{
if(n==1||m==1) return 1;
if(n<m) return q(n,n);
if(n==m) return 1+q(n,n-1);
if(n>m) return q(n,m-1)+q(n-m,m);
}
二、分治算法
2.1、棋盘覆盖
int tile = 1; //全局变量
int Board[128][128]; //全局变量
void ChessBoard(int lr,int lc,int sr,int sc,int size)
{ //lr:棋盘左上角行号,lc:棋盘 左上角列号,sr:特殊方格行号,sc:特殊方格列号,size:棋盘大小
if(size==1) return;
int t = tile++;
size = size/2;
//左上角棋盘
if(lr+size-1>=sr && lc+size-1>=sc){
ChessBoard(lr,lc,sr,sc,size); //特殊方格在左上角
}
else{ //特殊方格不在左上角,覆盖左上角棋盘的右下角方格
Board[lr+size-1][lc+size-1] = t;
ChessBoard(lr,lc,lr+size-1,lc+size-1,size);
}
//右上角棋盘
if(lr+size-1>=sr && lc+size-1<sc){
ChessBoard(lr+size-1,lc+size-1,sr,sc,size); //特殊方格在右上角棋盘
}
else{ //特殊方格不在 右上角
Board[lr+size-1][lc+size] = t; //覆盖右上角棋盘的左下角方格
ChessBoard(lr,lc+size,lr+size-1,lc+size-1,size);
}
//左下角棋盘如上
if(lr+size-1<sr && lc+size-1>=sc){
ChessBoard(lr+size-1,lc,sr,sc,size);
}
else{
Board[lr+size][lc+size-1] = t;
ChessBoard(lr+size,lc,lr+size,lc+size-1,size);
}
//右下角棋盘如上
if(lr+size-1<sr && lc+size-1<sc){
ChessBoard(lr+size,lc+size,sr,sc,size);
}
else{
Board[lr+size][lc+size] = t;
ChessBoard(lr+size,lc+size,lr+size,lc+size,size);
}
}
2.2、排序
①合并排序:时间复杂度为O(nlogn)
②快速排序:时间复杂度为O(nlogn)
2.3、二分搜索法:时间复杂度为O(logn)
int BinarySearch(int list[],int n,int x)
{
int left=0;
int right=n-1;
int middle;
while(left<=right)
{
middle=(left+right)/2;
if(x<list[middle]) right=middle-1;
if(x==list[middle]) return middle;
if(x>list[middle]) left=middle+1;
}
return -1;
}