全排列的计算

1.计算list[1,2,3]的全排列

2.代码

#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void swap(int *a,int *b){
	int temp = *a;
	*a = *b;
	*b = temp;
}

int perm(int list[],int k, int m){
	int i;
	if(k==m){
		for(i=0;i<m;i++)
			printf("%d",list[i]);
		printf("\n");
		}else{
			for(i=k;i<m;i++){
				swap(&list[k],&list[i]);
				perm(list,k+1,m);
				swap(&list[k],&list[i]);
			}
		}
	}


int main(){
	int n;
	int arr[]={1,2,3};
	n = sizeof(arr)/sizeof(arr[0]);
	perm(arr,0,n);
}

3.代码理解

(1)定义swap交换函数。

(2)定义全排列的运算逻辑(perm函数)。

(3)应用实例计算结果(main函数)。

以下是每个步骤的作用和算法的总体思路:

第一步:定义swap交换函数

void swap(int *a,int *b){
	int temp = *a;
	*a = *b;
	*b = temp;
}

这个swap函数的作用是对两个整数进行交换。函数通过指针参数ab接收要交换的两个整数的地址,然后利用一个临时变量temp来辅助完成交换。这样,调用swap函数后,传入的两个整数在内存中的值就被交换了。

第二步:定义全排列的运算逻辑(perm函数)

int perm(int list[],int k, int m){
	int i;
	if(k==m){
		for(i=0;i<m;i++)
			printf("%d",list[i]);
		printf("\n");
		}else{
			for(i=k;i<m;i++){
				swap(&list[k],&list[i]);
				perm(list,k+1,m);
				swap(&list[k],&list[i]);
			}
		}
	}

perm函数是全排列算法的核心。它采用递归的方式来生成数组list从索引km-1的所有排列。

(k是定义坐标索引位置,m是列表长度)

  • k等于m时,说明已经遍历到了数组的末尾,此时打印出当前的一个排列。
  • 否则,从km-1的每一个位置i,都执行以下操作:
    • 交换list[k]list[i]
    • 递归调用perm函数,以生成从k+1m-1的排列。
    • 回溯再次交换list[k]list[i],以撤销之前的交换操作,保证下一次循环时数组状态正确。(

这种递归和回溯的方式确保了每个元素都有机会被放在每个位置,从而生成所有可能的排列。

第三步:应用实例计算结果(main函数)

main函数中,首先定义了一个整数数组arr,并计算了数组的长度n。然后调用perm函数,以arr为参数,从索引0开始生成全排列。这样,程序的输出就是数组arr的所有可能排列。

4.总体思路

        全排列算法的核心在于递归和回溯。通过递归,算法可以逐步深入到数组的每一个位置;通过回溯,算法可以在生成一个排列后返回到上一个位置,继续生成其他的排列。这种递归和回溯的方式保证了算法能够生成所有可能的排列,而不会遗漏或重复。

        此外,需要注意的是,全排列算法的时间复杂度是O(n!),其中n是数组的长度。这是因为对于每个位置,都有n-k种选择(k是当前递归层级的起始位置),所以总的排列数是n的阶乘。因此,当数组长度较大时,全排列算法的运行时间可能会很长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值