直接或间接的调用自身的算法成为递归算法。用函数自身给出定义的函数称为递归函数。
例1:阶乘函数
int factorial(int n)
{
if(n==0) return 0;
return n*factorial(n-1);
}
例2:Fibonacci数列
int Fibonacci(int n)
{
if(n<1) return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
例3 全排列问题
//全排列问题
/*设 R={r1,r2,…,rn} 是要进行排列的 n 个元素,Ri=R-{ri}。
集合 X 中元素的全排列记为 perm(X)。
(ri)perm(X) 表示在全排列 perm(X) 的每一个排列前加上前缀得到的排列。
R 的全排列可归纳定义如下:
当 n=1 时,perm(R)=(r),其中 r 是集合 R 中唯一的元素;
当 n>1 时,perm(R)由 (r1)perm(R1),(r2)perm(R2),…,(rn)perm(Rn) 构成。
实现思想:将整组数中的所有的数分别与第一个数交换,这样就总是在处理后 n-1 个数的全排列。
【示例】
当 n=3,并且 E={a,b,c},则:
perm(E)=a.perm({b,c}) + b.perm({a,c}) + c.perm({a,b})
perm({b,c})=b.perm(c) + c.perm(b)
a.perm({b,c})=ab.perm(c) + ac.perm(b)
=ab.c + ac.b=(abc, acb)*/
#include
#include
using namespace std;
template
void Perm(Type list[], int k, int m )
{ //产生[list[k:m]的所有排列
if(k==m)
{ //只剩下一个元素
for (int i=0;i<=m;i++)
cout<
分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题。这些子问题相互独立且与原问题相同,递归的解决这些子问题,然后将各子问题的解合并并得到原问题的解。从分治法的一般设计模式可以看出,用它设计的程序一般时递归算法。
例1 二分搜索
template
int BinarySearch(Type a[],Type &x,int n)
{
int left,right=n-1;
while(left<=right)
{
int middle=(left+right)/2;
if(x==a[middle]) return middle;
if(x>a[middle]) left=middle+1;
else
right=middle-1;
}
return -1;//未找到
}
例2 归并排序
/*归并排序是利用归并的思想,采用分治策略,将问题分为一些小问题然后递归求解。在治阶段将分阶段得到****的各答案合在一起。比如一个{8,4,5,7,1,3,6,2}的数列分成{8,4,5,7}和{1,3,6,2}之后
****再分成{8,4},{5,7},{1,3},{6,2}再分成{8}{4}{5}{7}{1}{3}{6}{2},然后开始比较先比较8,4
****小的放前面之后合并,{4,8},以此类推合并{5,7},{1,3},{2,6}再比较合并{4,5,7,8},{1,****2,3,6},再比较合并{1,2,3,4,5,6,7,8}.
****归并是稳定排序,时间复杂度nlogn。
*/
#include
#include
//using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//template
//合并
void Merge(int A[], int TmpAry[], int Lpos, int Rpos, int RightEnd)
{
int i, LeftEnd, NumTypes, TmpPos;
LeftEnd = Rpos - 1;
TmpPos = Lpos; //临时数组指针
NumTypes = RightEnd - Lpos + 1;
while (Lpos <= LeftEnd&&Rpos <= RightEnd)
{
if (A[Lpos] <= A[Rpos])
{
TmpAry[TmpPos++] = A[Lpos++];
}
else
{
TmpAry[TmpPos++] = A[Rpos++];
}
}
while (Lpos <= LeftEnd)
{
TmpAry[TmpPos++] = A[Lpos++];
}
while (Rpos <= RightEnd)
{
TmpAry[TmpPos++] = A[Rpos++];
}
//复制
for (i = 0; i
例3 快速排序
/****
****采用三数中值法选区枢纽元
****在数据小于一定值时采用插入排序可以实现更高效率的排序
****
****
****
****
****/
#include
#define cutoff 3
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
template
void swap(Type &a, Type &b)
{
Type temp;
temp = a;
a = b;
b = temp;
}
template
void InsertSort(Type A[], int N)
{
int i, j;
Type temp;
for (i = 1; i= 0 && A[j - 1]>temp; j--)
A[j] = A[j - 1];
A[j] = temp;
}
}
//以三数中值作为基准值
template
Type Median3(Type A[], int left, int right)
{
int center = (left + right) / 2;
if (A[left]>A[center])
swap(A[left], A[center]);
if (A[left]>A[right])
swap(A[left], A[right]);
if (A[center]>A[right])
swap(A[center], A[right]);
//以上得到A[left]<=A[center]<=A[right]
swap(A[center], A[right - 1]);//隐藏枢纽元
return A[right - 1]; //返回枢纽元
}
template
void QSort(Type A[], int left, int right)
{
int i, j;
Type Pivot;
Pivot = Median3(A, left, right);
i = left; j = right - 1;
if (left + cutoff <= right)
{
for (;;)
{
while (A[++i]Pivot){}
if (i