递归与分治——全排列问题

递归函数:以层次来想函数递归,以深度来想递归出口。

问题:
给出一个集合,输入这个集合所有的排列集合。
例如:
输入:
{1,2,3}
输出:
{1,2,3}
{1,3,2}
{2,1,3}
{2,3,1}
{3,1,2}
{3,2,1}
思路:
全排列,就是不断交换两个元素,打印。
将所有可以交换的两个元素都交换一遍,都打印一遍,加上本来的排列,打印出来的就是我们的全排列。
所以我们焦点就放在了交换上面,怎么交换两个元素会使逻辑清晰。我们自己手写全排列的时候,一般都是先以第一个元素为首的全排列写完,再以第二个元素为首的全排列写完…直至写完。
我们先确定1这个位置不动,对剩下的数进行全排列,剩下的数的全排列第一个数加上1,那么以1为首的全排列就结束了。那么怎么对剩下的全排列进行排序呢?剩下的元素中,第一个元素不动,对剩下的元素进行全排列…一直递归,那么递归出口就是我们递归到最后一个元素,不需要对最后一个元素进行全排列。
看着代码分析会清晰一点:

void Perm(int* arr, int k, int m)
{
	if (k == m - 1)
	{
		for (int i = 0; i < m; i++)
		{
			printf("%2d", arr[k]);
		}
	}
	else
	{
		for (int i = k; i < m; i++)
		{
			swap(arr[i], arr[k]);
			Perm(arr, k + 1, m);
			swap(arr[i], arr[k]);
		}
	}
}

我们以层次来分析这个代码,首先将第一个元素和第一个元素本身进行交换,再将第一个元素本身和第二个元素交换,第一个元素和第三个元素交换…直至第一个元素和最后一个元素进行完交换。
第一层:产生【1,2,3】 【2,1,3】 【3,2,1】三个数组。下一层递归,会对数组的除去第一个元素的剩下元素进行交换。剩下元素的第一个元素和第一个元素交换,剩下元素的第一个元素和第二个元素交换,剩下元素的第一个元素和第三个元素交换…
在这里插入图片描述
递归函数我们按层次分析,出来的就会是一个树,在这里我们相当于在叶子节点时,打印数组的值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

孟小胖_H

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

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

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

打赏作者

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

抵扣说明:

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

余额充值