C语言实现全排列

#include<stdio.h>
#include<stdlib.h>
// 检查一个整数是否是活动的
bool isActiveble(int *p, int * direct, int index, int n) {
	int currentInteger = *(p + index);
	int curentIntegerDirect = *(direct + index);
	if( currentInteger == 1 ) {
		return false;
	}

	if( index == 0 && curentIntegerDirect == 0 || index == n - 1 && curentIntegerDirect == 1 ) {
		return false;
	}

	// 求currentInteger指向的数
	int directedInteger = 0;
	if( curentIntegerDirect == 0 ) {
		directedInteger = *(p + index - 1);
	} else {
		directedInteger = *(p + index + 1);
	}

	if( directedInteger < currentInteger ) {
		return true;
	}
	return false;
}


// 求当前集合数组中的最大活动整数的索引
int maxActivebleIntegerIndex(int *p, int *direct, int n) {
	int index = -1;  
	bool activeble = false;
	int i;
	for(i = 0; i < n; i++) {
		activeble = isActiveble(p, direct, i, n);
		if(activeble == true) {
			if(index == -1) {
				index = i;
				continue;
			}

			if(*(p + i) > *(p + index)) {
				index = i;
			}
		}
	}
	return index;
}


// 交换maxActivebleInteger和其箭头所指向的与其相邻的整数
void exchangeAdjacentInteger(int *p, int *direct, int maxActivebleIntegerIndex) {
	int curentIntegerDirect = *(direct + maxActivebleIntegerIndex);
	int tempDirect = curentIntegerDirect;
	int tempInteger = *(p + maxActivebleIntegerIndex);	

	// 交换数和数所对应的方向
	if( curentIntegerDirect == 0 ) {
		*(p + maxActivebleIntegerIndex) = *(p + maxActivebleIntegerIndex - 1);
		*(p + maxActivebleIntegerIndex - 1) = tempInteger;
		if(*(direct + maxActivebleIntegerIndex) != *(direct + maxActivebleIntegerIndex - 1)) {
			if(*(direct + maxActivebleIntegerIndex) == 0) {
				*(direct + maxActivebleIntegerIndex) = 1;
				*(direct + maxActivebleIntegerIndex - 1) = 0;
			} else {
				*(direct + maxActivebleIntegerIndex) = 0;
				*(direct + maxActivebleIntegerIndex - 1) = 1;
			}
		}
	} else {
		*(p + maxActivebleIntegerIndex) = *(p + maxActivebleIntegerIndex + 1);
		*(p + maxActivebleIntegerIndex + 1) = tempInteger;
		if(*(direct + maxActivebleIntegerIndex) != *(direct + maxActivebleIntegerIndex + 1)) {
			if(*(direct + maxActivebleIntegerIndex) == 0) {
				*(direct + maxActivebleIntegerIndex) = 1;
				*(direct + maxActivebleIntegerIndex + 1) = 0;
			} else {
				*(direct + maxActivebleIntegerIndex) = 0;
				*(direct + maxActivebleIntegerIndex + 1) = 1;
			} 
		}
	}
}


// 交换所有大于当前最大活动整数的数所对应的方向
void exchangeDirects(int *p, int *direct, int maxActivebleInteger, int n) {
	int i;
	for(i = 0; i < n; i++) {
		if(*(p + i) > maxActivebleInteger) {
			if(*(direct + i) == 0) {
				*(direct + i) = 1;
			} else {
				*(direct + i) = 0;
			}
		}
	}
}


// 输出集合数组的当前排列
void printCurrentArrange(int *p, int n) {
	int i;
	for(i = 0; i < n; i++) {
		printf("%d ",*(p + i));
	}
	printf("\n");
}


int main() {
	// 定义并输入一个正整数n
	int n = 0;
	printf("请输入n值: ");
	scanf("%d",&n);
	if(n <= 1) {
		if(n == 1) {
			printf("%d\n",n);
		}
		exit(0);
	}

	// 为数列和方向数组分配地址
	int *p = (int *) malloc (sizeof(int) * n);
	int *direct = (int *) malloc (sizeof(int) * n);

	// 初始化集合数组和方向数组
	int i;
	for(i = 0; i < n; i++) {
		*(p + i) = i + 1;
		*(direct + i) = 0;
	}

	// 最大活动整数的索引
	int index = n - 1;
	// 最大活动整数
	int maxActivebleInteger = *(p + index);
	printCurrentArrange(p, n);
	while(index != -1) {
		// 交换最大活动整数和其箭头所指向的与其相邻的整数
		exchangeAdjacentInteger(p, direct, index);
		// 交换所有满足p > m的整数p的方向
		exchangeDirects(p, direct, maxActivebleInteger, n);
		// 打印当前排列
		printCurrentArrange(p, n);
		// 求出最大的活动整数
		index = maxActivebleIntegerIndex(p, direct, n);
		maxActivebleInteger = *(p + index);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值