全排列递归算法

本文详细介绍了全排列的概念及递归算法实现过程,并通过具体示例{1,2,3,4,5}

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

全排列是将一组数按一定顺序进行排列,如果这组数有n个,那么全排列数为n!个。现以{1, 2, 3, 4, 5}为
例说明如何编写全排列的递归算法。

1、首先看最后两个数4, 5。 它们的全排列为4 5和5 4, 即以4开头的5的全排列和以5开头的4的全排列。
由于一个数的全排列就是其本身,从而得到以上结果。
2、再看后三个数3, 4, 5。它们的全排列为3 4 5、3 5 4、 4 3 5、 4 5 3、 5 3 4、 5 4 3 六组数。
即以3开头的和4,5的全排列的组合、以4开头的和3,5的全排列的组合和以5开头的和3,4的全排列的组合.
从而可以推断,设一组数p = {r1, r2, r3, ... ,rn}, 全排列为perm(p),pn = p - {rn}。
因此perm(p) = r1perm(p1), r2perm(p2), r3perm(p3), ... , rnperm(pn)。当n = 1时perm(p} = r1。
为了更容易理解,将整组数中的所有的数分别与第一个数交换,这样就总是在处理后n-1个数的全排列。

算法如下:
#include <stdio.h>

int n = 0;

void swap(int *a, int *b)
{
int m;
m
= *a;
*a = *b;
*b = m;
}
void perm(int list[], int k, int m)
{
int i;
if(k > m)
{
for(i = 0; i <= m; i++)
printf(
"%d ", list[i]);
printf(
"\n");
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 list[] = {1, 2, 3, 4, 5};
perm(list,
0, 4);
printf(
"total:%d\n", n);
return 0;
}

### C语言实现升序全排列递归算法 为了生成升序的全排列,在编写C语言代码时,可以采用递归方法来处理这个问题。下面是一个具体的例子: ```c #include <stdio.h> #include <string.h> // 打印当前数组状态 void printArray(char *array, int size) { for (int i = 0; i < size; ++i) printf("%c", array[i]); printf("\n"); } // 检查字符是否已经在数组中存在 bool contains(const char *str, int start, int end, char ch) { for (int i = start; i <= end; ++i) if (str[i] == ch) return true; return false; } // 递归函数用于生成全排列 void permuteInOrder(char *chars, bool *used, char *current, int index, int length) { if (index == length) { // 当前索引等于长度,则打印结果 printArray(current, length); return; } for (int i = 0; i < strlen(chars); ++i) { if (!contains(current, 0, index - 1, chars[i])) { // 防止重复元素进入同一位置 current[index] = chars[i]; used[i] = true; permuteInOrder(chars, used, current, index + 1, length); // 回溯操作 used[i] = false; } } } // 初始化调用接口 void generatePermutations(char *inputString, int n) { int len = strlen(inputString); char result[n]; // 存储每次的结果 memset(result, '\0', sizeof(result)); bool visited[len]; for (int i = 0; i < len; ++i) visited[i] = false; qsort(inputString, len, sizeof(char), (int(*)(const void*, const void*))strcmp); // 排序输入字符串以确保顺序性[^3] permuteInOrder(inputString, visited, result, 0, n); } ``` 上述代码实现了基于给定字符集`inputString`按照字典序输出指定长度`n`的所有可能组合的功能。这里的关键在于通过`qsort()`预先对输入进行了排序,从而保证了最终得到的是有序序列。 #### 函数解释: - `printArray`: 输出当前形成的排列。 - `contains`: 判断某个字符是否已经存在于当前位置之前的排列部分。 - `permuteInOrder`: 主要负责递归构建每一个新的排列项,并利用回溯法尝试不同的可能性直到形成完整的排列为止。 - `generatePermutations`: 提供了一个简单的API入口,接受原始字符列表以及期望获得的排列长度作为参数。 此方案不仅考虑到了避免重复元素在同一位置上的放置问题,还通过对初始字符集进行预排序的方式保障了输出结果遵循严格的字典序规则[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值