本来这篇早就该写了,但一直没有时间,鸽到了现在,略微有点愧疚。
题目
输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,⋯,a**n排在序列b1,b2,⋯,b**n之前,如果存在k使得a1=b1,⋯,a**k=b**k 并且 a**k+1<b**k+1。
讲真这题目确实抽象,我们看个例子

让我想起了初中的数学题。。。
分析
在我看来,递归确实难以理解,但这种题,每一位都循环着走是一种解法,但循环次数是随着输入的值动态变化的。以我目前的知识量,好像只有递归能解决这类问题。
那么以123为例,它是怎样变化为其他5中样式的呢?
123->132 数字3移动到第二个位置上,数字2向后挪一位
123->213 数字2移动到第一个位置上,数字1向后挪一位
123->231 数字2移动到第一个位置上,数字1向后挪一位成213;数字3移动到第二个位置上,数字1向后挪一位
以此类推
因此,我们需要一个函数LeftSwap,实现一个数字往前挪,这个数字后面的数依次往后挪一位。
但是,我们的变化是基于123这个基础的,所以需要一个函数RightSwap来还原为最初的样子。其实就是挪动的数字回原位,其他数字往前挪一位。
问题解决一半了,剩下的就是递归。递归的关键就是出口,循环条件的改变。
在左边数的下标等于右边数的下标的时候,就要跳出这一次递归,然后输出递归的结果。
代码分析
我们将代码拆分来看。
主函数
利用循环给每数组赋值,进行递归,令0为左边值的下标,n-1为右边的下标。
#include<stdio.h>
#define MAX 9
}
int main()
{
int n, a[MAX];
scanf("%d", &n);
int i;
for (i = 0; i < n; i++)
{
a[i] = i + 1;
}
Array(a, 0, n - 1);
return 0;
}
递归
递归函数需要三个变量,数组,左边的下标Left,右边的下标Right。当Left = Right时,说明处理到最后一个元素了,这时到达递归终点,输出这一次的结果,然后返回到数组上一次递归调用的样子,再次递归。下一次递归,我们让Left+1,继续进行。
void Array(int

本文详细介绍了如何使用递归实现1到n的全排列输出,通过左移和右移函数来改变数字顺序,遵循字典序原则。代码以C语言编写,包括主函数、递归函数和变换函数,实现了全排列的生成。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



