1、算法学习笔记--递归与分治

一、递归
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)组成。
《1、算法学习笔记--递归与分治》

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;
}
    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/William_Sunrise/article/details/82463812
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞