C语言 全排列的实现

首先是一维数组的全排列,半个多月前在PAT上做了一个题,深有体会,可以深入理解递归这东西。

-----------------------------------------------------------------------------------------------------------------

请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。

输入格式:

输入给出正整数n<10)。

输出格式:

输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,,an排在序列b1,b2,,bn之前,如果存在k使得a1=b1,,ak=bk 并且 ak+1<bk+1

输入样例:

3

输出样例:

123
132
213
231
312
321

以下代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//指针变量相当于一个新的变量,在函数中必须建一个指针变量指向这个指针变量才能改变这个变量的值


void Print(int*a, int n) {
	for (int i = 1; i <= n; i++) {
		if (i == n)	printf("%d\n", a[i]);
		else printf("%d ", a[i]);
	}
}
void perm(int*a, int*b,int n,int Index) {
	if (Index== n+1) {
		static int cnt = 0;
		printf("第%03d次排序为:", ++cnt);
		Print(a, n);
		return;
	}
	for (int i = 1; i <= n; i++) {
		if (!b[i]) {
			a[Index] = i;
			b[i] = 1;
			perm(a, b, n, Index + 1);
			b[i] = 0;
		}
	}
	return;
}
int main() {
	int n;
	int a[51], b[51] = { 0 };
	printf("输入n:\n");
	//可最大计算出50个数的全排列
	//其中a是输出数列,b是索引数列,它的索引用来锁定和输入a的数值
	scanf("%d", &n);
	//输入n来全排列1~n的数组
	perm(a, b, n, 1);
	return 0;
}

通过数组b的0,1值和递归来对数组a进行全排列的赋值

--------------------------------------------------------------------------------------------------------------------------

接下来是字符的全排列
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//全排列字符数组
void permChar(char*a,int start) {
	int i;
	static int cnt = 0;
	if (!a[start]) {
		printf("第%d次排序:", ++cnt);
		for (i = 0; i < start; i++) {
			printf("%c", a[i]);
		}
		printf("\n");
	}
	for (i=start; a[i]; i++) {
		char temp = a[i];
		a[i] = a[start];
		a[start] = temp;
		permChar(a, start+ 1);
		temp = a[i];
		a[i] = a[start];
		a[start] = temp;
	}
}
int main() {
	char a[50] = "Miku";
	permChar(a, 0);
	return 0;
}

通过start索引上的字符是否为'\0'来进行判定。

--------------------------------------------------------------------------------------------------------------------

字符串数组的全排列:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//字符串二维数组的全排列(多维数组排列可据此叠加)
void swap1(char**a, char**b) {
	char*temp = *a;
	*a = *b;
	*b = temp;
}
void swap2(char*a[],char*b[],int len) {
	for (int i = 0; i < len; i++) {
		swap1(a + i, b + i);
	}
}//只是让其内部的字符串指针产生改变
//并不是取字符串数组的指针来改变字符串数组的位置
void permStr(char*a[][4], int length,int len,int start) {
	static int cnt;
	if (start == length) {
		printf("\n第%d次排序:\n",++cnt);
		for (int i = 0; i < length; i++) {
			for (int j = 0; j < len; j++) {
				printf("%s ", a[i][j]);
			}
			printf("\n");
		}
	}
	for (int i = start; i < length; i++) {
		swap2(a[start], a[i],len);
		permStr(a, length, len, start + 1);
		swap2(a[start], a[i], len);
	}
}
int main() {
	char*str[][4] = {
		{"C","Y","F","E"},
		{"cherish","you","for","ever"},
		{"crying","yet","for","everything"}
	};
	int length = 3;
	permStr(str, length, 4, 0);
}

当时试想着实现的,其实全排列模板都一样,就是二维数组在全排列的交换函数有所区别。

有利于对指针更深层次的理解:指针变量在这里相当于一个新的变量,在函数中必须建一个指针变量指向这个指针变量才能改变这个变量的值

  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值