递归函数:以层次来想函数递归,以深度来想递归出口。
问题:
给出一个集合,输入这个集合所有的排列集合。
例如:
输入:
{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】三个数组。下一层递归,会对数组的除去第一个元素的剩下元素进行交换。剩下元素的第一个元素和第一个元素交换,剩下元素的第一个元素和第二个元素交换,剩下元素的第一个元素和第三个元素交换…
递归函数我们按层次分析,出来的就会是一个树,在这里我们相当于在叶子节点时,打印数组的值。
标签:arr,排列,第一个,递归,分治,交换,元素 来源: https://blog.csdn.net/yi_chengyu/article/details/120580624
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。