输入一个数,打印从 1 ~ n 的全排列(C语言 字典序法)

字典序法实现全排列

  1. 算法思想在permutation( ) 函数中体现
  1. 代码要求:
    输入一个数,将从 1 ~ n 的全排列打印出
A. 字典序算法思想:
  1. 从右往左, 找到第一个右邻大于自己的数Array[a]
  2. 从右往左, 找出第一个大于Array[a]的数,记为Array[b]
  3. 交换Array[a]和Array[b]
  4. 交换前Array[a]下标 “后面的” 数据由小往大排列
B. 例:输入5

在这里插入图片描述

C. 具体代码

#include <stdio.h>
void permutation(int n);/*排列过程,important!!!*/ 
void creatArray(int array[], int n);/*创建从 1 到 n 的数组*/ 
int  calculate(int n);/*计算所有的排列方式*/ 
void print(int array[], int n);/*打印数组数据*/ 
int  getArray_A(int array[], int n);/*获取Array[a]的下标*/ 
int  getArray_B(int array[], int array_a, int n);/*获取Array[b]的下标*/ 
void swap(int *a, int *b);/*交换数组中的两个数,用于交换Array[a],Array[b]*/
void sort(int array[], int start, int end);/*排序函数,用于每次循环的Array[a]后数组数据的排序*/ 


int main(void)
{
	int n; 
	printf("Please input a number:");
	scanf("%d", &n);
	permutation(n); /*这个英文单词意思是排列,英语没学好,查字典的*/ 
	return 0;
}


/*排列过程,important!!!*/ 
void permutation(int n){
	int Array[n];		/*从一到 n 的数组*/ 
	int num_permutation;/*接收组合数个数*/ 	 
	int Array_A, Array_B;/*接收获得需要交换值的下标*/ 
	
	creatArray(Array, n);						/*1. 创建一个从一到 n 的数组*/
	
	num_permutation = calculate(n);				/*2. 计算组合数个数*/ 
	
	for(int i=0; i<num_permutation; i++){		/* 3. 进入循环*/ 
		print(Array, n);							/*a. 打印排列好的数组*/ 
		
		Array_A = getArray_A(Array, n);				/*b. 获取Array[a]的下标:从右往左,找到第一个右邻大于自己的数*/ 
		
		Array_B = getArray_B(Array, Array_A, n);	/*c. 获取Array[b]的下标:从右往左,找出第一个大于Array[a]的数*/
		
		swap(Array+Array_A, Array+Array_B);			/*d. 交换Array[a]和Array[b]*/ 
		
		sort(Array, Array_A+1, n);					/*e. 将Array[a] "后面的" 数据由小往大排列*/ 
	} 
}




/*创建从 1 到 n 的数组*/ 
void creatArray(int array[], int n){
	for(int i=0; i<n; i++){
		array[i] = i + 1;
	}
	return array;
}
/*计算所有的排列方式*/ 
int calculate(int n){
	int num = 1;
	for(int i=1; i<=n; i++){
		num *= i;
	}
	return num;
}
/*打印数组数据*/ 
void print(int array[], int n){
	for(int i=0; i<n; i++){
		printf("%d", array[i]);
	}
	printf("\n");
}
/*获取Array[a]的下标*/ 
int getArray_A(int array[], int n){
	for(int i=n; i>0; i--){
		if(array[i - 1] < array[i]){
			return i - 1;
		}			
	}
}
/*获取Array[b]的下标*/ 
int getArray_B(int array[], int array_A, int n){
	for(int i=n; i>0; i--){
		if(array[i] > array[array_A]){
			return i;
		}
	} 
}
/*交换数组中的两个数,用于交换Array[a],Array[b]*/ 
void swap(int *a, int *b){
	int temp = *a;
	*a = *b;
	*b = temp;
}
/*排序函数,用于每次循环的Array[a]后数组数据的排序*/ 
void sort(int array[], int start, int end){
	for(int i=0; i<end-start-1; i++){
		for(int k=start; k<end-i-1; k++){
			if(array[k] > array[k + 1]){
				int temp = array[k];
				array[k] = array[k + 1];
				array[k + 1] = temp;
			}
		}
	}
}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值