分治策略(递归,排列问题)

注:【算法学习】转载请注明出处!

【算法学习】系列源码均在Linux上编译运行,g++的版本使用的是:



1、递归概念


       直接或者间接调用自身的算法叫做递归算法。用函数自身给出定义的函数称为递归函数。有些数据结构,比如二叉树等,由于自身固有的递归特性,特别适合用递归来描述。

ex1: 阶乘问题


对于上述阶乘问题显然可以使用循环的方式来解决。这里使用递归来实现,初步感受递归的使用方式。

#include <iostream>
using namespace std;

int Factorial(int n)
{
	if(0 > n)
	{
		cout<< "Error!" <<endl;
	}
	else if(0 == n)
	{
		return 1;
	}
	else 
	{
		return ( n * Factorial(n-1));
	}
}


int main(int argc, char *argv[])
{
	int result = Factorial(5);
	cout<< result <<endl;
	return 0;
}
运行结果:



ex2.斐波那契数列


Fibonacci数列是比较常见的递归问题,其衍生出来的问题也很多。

#include <iostream>
using namespace std;


int Fibonacci(int n)
{
	if(0 > n) return -1;
	else if(0 == n) return 1;
	else if(1 == n) return 1;
	else
	{
		return (Fibonacci(n-2) + Fibonacci(n - 1) );
	}
	
}

int main(int argc, char *argv[])
{
	for(int i = 0; i < 9; ++i)
	{
		cout<< Fibonacci(i) <<" ";
	}
	cout<<endl;
	return 0;
}

运行结果:



       对比使用循环的方式,递归算法结构清晰,可读性强,且容易用数学归纳法证明算法的正确性。但是递归算法无论从耗费的时间还是从占用的空间角度看,递归算法的效率都比较低。所以常常在递归算法消除递归调用。

     

2、分治策略 


       分治策略的思想是将一个比较大的问题分解成若干个小的问题来求解,各个小问题求解后的结果综合起来得到原问题的解。


3、排列问题



问题描述: 输入n个元素,对这个n个元素进行全排列,列举出所有的结果。

问题分析:第一个元素不动,对后面n-1个元素进行全排列,这样得到的就是以第一个元素为首的所有排列结果,然后将第二个元素作为首元素,对后面n-1个元素进行全排列,依次下去……

总结上述规律,可以将第一个元素分别和数列中的每一个元素作交换,然后递归求解。

 代码实现:

#include <iostream>
using namespace std;

int item = 0;

inline void swap(char &a, char &b)
{
	char tmp = a;
	a = b;
	b = tmp;
}

void Perm(char str[], int m, int n)
{
	if(m == n)
	{
		for(int i = 0; i < n; ++i)
		{
			cout<< str[i] << " ";
		}
		item++;
                cout<<endl;
	}
	else
	{
		for(int i = m; i < n; ++i)
		{
			swap(str[m],str[i]);
			Perm(str, m+1, n);
			//cout<< str[i] << " ";
		}
	}
}


int main(int argc, char *argv[])
{
	char str[5] = "abcd";
	Perm(str, 0, 4);
        cout<<"Perm Times:"<<item<<endl;
	return 0;
}
运行结果:



注:【算法学习】系列博客来源于《计算机算法设计与分析》王晓东的理解及相关笔记,转载请注明出处!



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空空的司马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值