输入一个数,打印从 1 ~ n 的全排列
123
132
213
231
321
312
全排列就是从第一个数字起每个数分别与它后面的数字交换。
#include <stdio.h>
void permutation(int arr[], int p, int max_key);/*全排列递归函数*/
void creatArray(int array[], int n);/*创建1~n的数组*/
void swap(int arr[], int i, int j);/*交换数组的两个元素*/
void printArray(int arr[], int len);/*遍历打印数组*/
int main(void)
{
int n, len;
printf("Please input a number:");
scanf("%d", &n);
int arr[n];/*从 1 ~ n 的数组*/
len = sizeof(arr) / sizeof(arr[0]); /*计算数组的长度*/
creatArray(arr, n);/*创建一个从 1 ~ n 的数组*/
/*以上都是准备工作*/
permutation(arr, 0, len-1);/*进入排列,传入用于交换的下标 和 最大下标*/
return 0;
}
/*用于递归的函数*/
void permutation(int arr[], int p, int max_key){
if (p == max_key){
printArray(arr, max_key + 1 );
}
for (int i = p; i <= max_key; ++i){
swap(arr, p, i);
permutation(arr, p + 1, max_key);
swap(arr, p, i); /*换完之后,进入函数递归,出来要换回来*/
}
}
/*创建从 1 到 n 的数组*/
void creatArray(int array[], int n){
for(int i=0; i<n; ++i){
array[i] = i + 1;
}
}
/*交换数组的两个元素*/
void swap(int arr[], int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/*遍历打印数组*/
void printArray(int arr[], int len){
for (int i = 0; i < len; ++i){
printf("%d ", arr[i]);
}
printf("\n");
}
从进入permutation()开始,到大循环两次过程,可以找出规律了(最后两次就不写了):
发现优化:很多的交换过程都是无效的的:
所以在permutation()中加入了条件判断
#include <stdio.h>
void permutation(int arr[], int p, int max_key);/*全排列递归函数*/
void creatArray(int array[], int n);/*创建1~n的数组*/
void swap(int arr[], int i, int j);/*交换数组的两个元素*/
void printArray(int arr[], int len);/*遍历打印数组*/
int main(void)
{
int n,len;
printf("Please input a number:");
scanf("%d", &n);
int arr[n];/*从 1 ~ n 的数组*/
len = sizeof(arr)/sizeof(arr[0]); /*计算数组的长度*/
creatArray(arr, n);/*创建一个从 1 ~ n 的数组*/
/*以上都是准备工作*/
permutation(arr, 0, len-1);/*进入排列,传入用于交换的下标 和 最大下标*/
return 0;
}
/*用于递归的函数*/
void permutation(int arr[], int p, int max_key){
if (p == max_key){
printArray(arr, max_key + 1 );
}
for (int i = p; i <= max_key; i++){ /*优化*/
if(p!=i){
swap(arr, p, i);
}
permutation(arr, p + 1, max_key);
if(p!=i){ /*优化*/
swap(arr, p, i);
}
}
}
/*创建从 1 到 n 的数组*/
void creatArray(int array[], int n){
for(int i=0; i<n; i++){
array[i] = i+1;
}
}
/*交换数组的两个元素*/
void swap(int arr[], int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/*遍历打印数组*/
void printArray(int arr[], int len){
for (int i = 0; i < len; i++){
printf("%d ", arr[i]);
}
printf("\n");
}
最后发现递归树挺好用的:
可以参考一下大佬的