参考课本:精通C++(第9版)
递归函数:一个自我调用的函数
函数也可以调用它自己
例子:
#include<iostream>
void message(int times)
{
if (times > 0)
std::cout << "You are pretty beautiful!!!\n" <<std:: endl;
message(times - 1);//控制权
}
int main()
{
message(3);
return 0;
}
函数被调用4次,所以递归的深度为:4;
直接递归与间接递归:一个直接调用自己的函数,另一个间接调用,A调B,B调C,C调A
例子:递归计算阶乘数:接收一个整型参数并计算其阶乘
factorial(n)=n*factorial(n-1);如果n>1;
=1;n=1
#include<iostream>
//#include<string>
int factorial(int arg)
{
if (arg == 1)
return 1;
else
return arg * factorial(arg - 1);
}
int main()
{
int number;
std::cout << "Enter an number and I will dispaly it's factorial:\n";
std::cin >> number;
std::cout << "It is equal to " << factorial(number) << std::endl;
return 0;
}
递归计算最大公约数:greastest common divisior,GCD
辗转相除法
辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法。
来自 https://baike.baidu.com/item/最大公约数
gcd(x,y)=y;如果y除以x没有余数
=gcd(y,x/y的余数)
#include<iostream>
//#include<string>
int gcd(int x, int y)
{
if ( x% y== 0)
return y;
else
return gcd(y, x % y);
}
int main()
{
int x, y;
std::cout << "Enter two integers:\n";
std::cin >> x >> y;
std::cout << "The two integers' greatest common divisor is " << gcd(x, y) << std::endl;
return 0;
}
#include<iostream>
//#include<string>
int fib(int n)
{
if (n <= 0)
return 0;
else if (n == 1)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
int main()
{
std::cout << "The first Fibonacci numbers are: \n";
for (int i = 0; i < 10; i++)
{
std::cout << fib(i) << std::endl;
}
return 0;
}
例子:递归二分搜索函数:二分搜索可以定义为一个递归函数
int binarySearch(const int array[], int first ,int last ,int value)
主要部分:
int middle;
if(first>last)
return -1;
if(array[middle]<value)
return binarySearch( const int array[], int middle+1 ,int last ,int value)
if(array[middle]>value)
return binarySearch( const int array[], int first ,int middle-1 ,int value)
array是要搜索的数组,形参first与last保留了搜索范围,value要找到的目标
#include<iostream>
int binarySearch(const int list[], int first, int last, int value)
{
int middle=(first+last)/2;
bool found = false;
if (first > last)
return -1;
if (list[middle] == value)
return middle;
if (list[middle] > value)
return binarySearch(list, first, middle - 1, value);
else
return binarySearch(list, middle + 1, last, value);
}
const int SIZE = 20;
int main()
{
int array[SIZE] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,89,99,100 };
int number, results;
std::cout << "Enter an integer to search in the list\n";
std::cin >> number;
results = binarySearch(array, 0,SIZE-1, number);
if (results == -1)
std::cout << "That's number isn't exist in the array\n";
else
std::cout << "the number " << number << " you had search, is on the position" << results + 1 << std::endl;
return 0;
}
例子:程序解决与程序设计:快速排序算法
使用递归有效地对列表进行排序:
通常为3个形参的递归函数,形参可以定义要排序的数组的一部分
• 一个包含项目列表的数组arr
• 两个下标start与end
伪代码:
void 快速排序(int arr[],int start, int end)
{
If(start<end)
{
Int p=partition(arr,start,end);//给数组分区,并获得基元素(pivot)
//排序小于基元素
快速排序(arr,start,p-1);
//排序大于基元素
快速排序(arr,p+1,end)
}
}
难点:理解分割数组arr[start…end]过程,
分区算法选择arr[start]作为基元素,分阶段在基元素左侧,右侧构建两个子元素
重复分区,排序:排刚好位于子列表2末尾的x,假设x<pivot,要添加到start组的子列表1中
方法:添加到子列表1的末尾,放在pivot的左边,
策略:把x存储在临时位置,将子列表2的元素向右移动,然后把x放入pivot腾出来的位置,效率低下
把x与刚好在基准元素pivot右侧的y元素换,然后再让x与pivot交换;第一次交换将y(>=pivot)放在子列表2的末尾,同时把x换到与pivot相邻位置,第二次交换,把x放在了pivot左侧
不断重复,直到整个列表分区
执行分区的partition函数代码(不完整)
int partition(int arr[],int start, int end)
{
int pivotValue=arr[start];
int pivotposition=start;
//重新排列区分子范围中除基准元素之外的从start到end的元素
for(int pos=start+1;pos<=end;pos++)
{
If(arr[pos]<pivotValue)
{
Swap(arr[pivotPosition+1],arr[pos];//交换位置
Swap(arr[pivotPosition],arr[pivotPosition+1];
pivotPosition++;
}
}
return pivotPosition;
}
代码:
#include<iostream>
#include<algorithm>//swap函数
using namespace std;
int quicksort(int[], int, int);//快速排序
int partition(int[], int, int);//分区
int main()
{
const int SIZE = 10;
int array[SIZE] = { 17,45,6,89,65,33,83,24,45,76 };
for (int k = 0; k < SIZE; k++)
{
cout << array[k] << " " ;
}
cout << endl;
quicksort(array, 0, SIZE);
for (int k = 0; k < SIZE; k++)
{
cout << array[k] << " " ;
}
cout << endl;
return 0;
}
int partition(int arry[], int start, int end)
{
int pivotValue = arry[start];
int pivotPosition = start;
//重新排列区分子范围中除基准元素之外的从start到end的元素
for (int pos = start + 1; pos <= end; pos++)
{
if(arry[pos] < pivotValue)
{
swap(arry[pivotPosition + 1], arry[pos]);//交换位置
swap(arry[pivotPosition], arry[pivotPosition + 1]);
pivotPosition++;
}
}
return pivotPosition;
}
int quicksort(int arry[], int start, int end)
{
if (start < end)
{
int p = partition(arry, start, end);//给数组分区,并获得基准点
quicksort(arry, start, p - 1);//获得小于基准元素的区间
quicksort(arry, p + 1, end);//获得大于基准元素的区间
}
return 0;
}
ps:貌似我用vs跑出来有一点小bug,但是dev跑出来没有问题
例子:汉诺塔
cheer up!