全排列问题。(进一步理解递归的含义,单步运行观察每一个变量的变化)
给定一个数组,求这个数组的全排列。
列如:a={1,2,3,4}
,对数组a求全排列
结题思路:
将a数组中的元素依次放在第一个位置然,对剩下的元素进行全排列。剩下元素全排列依然是,将剩下的元素依次放在第一个位置,对剩下的元素进行全排列。直到剩下的元素个数为一个时,排列结束。
这里我给出固定元素1,对元素2、3、4进行全排列的一种情况,其他情况类似
代码
#include<iostream>
using namespace std;
void Swap(int & a, int &b)
{ //将不是第一个元素的元素与第一个元素交互位置
int t = a;
a = b;
b = t;
}
void Perm(int list[], int k, int m)//从第k位到第m位全排列
{
if (k == m) //当k为最后一个元素时,不用交互了,直接输出。
{
for (int i = 0; i <= m; i++)
cout << list[i];
cout << endl;
}
//还有多个元素待排列,递归产生排列
for (int i = k; i <= m; i++)
{
//第一个Swap函数中的 list[k] 一直是指向的待排列序列的第一个位置, list[i]则是待排列序列中的要与第一个位置的元素交互的元素
Swap(list[k], list[i]); //交互位置
Perm(list, k + 1, m); // 当上一个Swap交互完成时,然后判断下一个元素
Swap(list[k], list[i]); //当上面两个函数调用完成时,将数组还原成最初的形式
}
}
int main()
{
int list[] = {1,2,3};
Perm(list, 0, 2); // 0,2表示0号元素到2号元素做全排列
return 0;
}
对于这段核心代码代码:
其中的变量:i
始终是要换到第一个位置的元素的下标,变量:k
是第一个位置元素的下标
for (int i = k; i <= m; i++)
{
//第一个Swap函数中的 list[k] 一直是指向的待排列序列的第一个位置, list[i]则是待排列序列中的要与第一个位置的元素交互的元素
Swap(list[k], list[i]); //交互位置
Perm(list, k + 1, m); // 当上一个Swap交互完成时,然后判断下一个元素
Swap(list[k], list[i]); //当上面两个函数调用完成时,这个函数执行,将数组还原成最初的形式
}
结果:
总结
递归过程确实比较难理解,大家可以在Excel表中画一下递归过程,这样有助于大家理解整个过程!!!