递归的简单应用(入门)C++

参考课本:精通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!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值