c语言函数全排列 c语言中的排序函数

c语言全排列

这个说起来太麻烦了, 我找了一个, 你看看行不, 不可以的话, 私聊吧.

创新互联公司专注于企业营销型网站建设、网站重做改版、双柏网站定制设计、自适应品牌网站建设、H5页面制作商城网站开发、集团公司官网建设、外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为双柏等各大城市提供网站开发制作服务。

全排列用的是 置换算法,

算法这东西重在理解。具体代码并不那么重要。

全排列是将一组数按一定顺序进行排列,如果这组数有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语言怎么实现有重复元素的全排列?

整体思路就是利用回溯的思想,也可认为是深度优先搜索

从字符串第一位idx=0开始,每次递归都从s[idx]之后选择一个字符与s[idx]交换

因为可能有重复字符,可使用哈希数组标记当前循环每个字符是否被选择

因为字符范围不超过ASCII码,所以使用128空间的数组足够用来标记了

选择好当前字符s[i]并与s[idx]交换之后,递归调用继续排列下一位s[idx+1]

注意这里要进行回溯,即不选s[i]而选择之后的某个字符交换到s[idx]

所以要将之前的s[i]与s[idx]交换过来,恢复原状,才能循环判断下一个选择

具体代码截图如下:

运行结果如下:

结果正确,望采纳~

附源码:

#include stdio.h

#include stdlib.h

#include string.h

#define MAXN 1000000 // 排列总数可能很多

int num = 0; // 记录排列总数

char *res[MAXN] = {NULL}; // 指针数组保存排列结果

void swap(char *x, char *y) { // 交换两个字符变量的内容

char ch = *x;

*x = *y;

*y = ch;

}

void perm(char *s, int n, int idx) { // 回溯产生字符串全排列

if (idx == n) { // 已排列到字符串结尾

  res[num] = (char *)malloc(sizeof(char) * (n + 1));

  //printf("%s\n", s); // 输出当前排列

  strcpy(res[num], s); // 保存当前排列

  num++; // 排列总数加1

  return;

}

int i, hash[128] = {0}; // 哈希数组,标记每个字符是否被选择

for (i = idx; i n; i++) {

  if (hash[s[i]] == 1)

      continue; // 跳过已被标记过的重复字符

  hash[s[i]] = 1; // 选过的话在数组中标记为1

  swap(s[idx], s[i]); // 选择s[i]交换到s[idx]

  perm(s, n, idx + 1); // 递归,继续s[idx+1]的选择

  swap(s[idx], s[i]); // 回溯,当前不选择s[i],而选择其他字符

}

}

int main() {

int n, i;

scanf("%d", n);

char *s = (char *)malloc(sizeof(char) * (n + 1));

scanf("%s", s);

perm(s, n, 0);

printf("一共有%d种排列:\n", num); // 输出排列总数

for (i = 0; i num; i++) { // 输出所有排列

  printf("%s\n", res[i]);

  free(res[i]); // 释放内存空间

}

free(s);

return 0;

}

C语言的全排列问题!急!

这其实是一个递归

递归函数

意思是这样的

比如有n个数

1

2.。。。n

把1

从第一个开始

往后

与每个数开始交换

然后

第一个数就算定了

后面的

第2个到第n个当成一个整体

再进行这个函数递归

也就是说

第二个到第n个进行全排列

这样下去

当全排列到最后一组数

即第n个数一个的时候

递归退出条件就出来了

就可以输出全排列的值了

当然

最后别忘记把交换的数还原

再进行下一次交换

递归哦

所以最后一局的交换也是很重要的

听完我的解释

再好好琢磨一下

相信你一定会明白的

要是还是不懂可以继续追问我

c语言,函数全排列,求代码,如图?

#include stdio.h

char c,s[10];

int n;

void pern(int k)

{int i;

if(k==n)

printf("%s\n",s+1);

else

for(i=k;i=n;i++)

{c=s[k];s[k]=s[i];s[i]=c;

pern(k+1);

c=s[k];s[k]=s[i];s[i]=c;

}

}

int main()

{ int i;

scanf("%d",n);

for(i=1;i=n;i++)

s[i]='0'+i;

pern(1);

return 0;

}


名称栏目:c语言函数全排列 c语言中的排序函数
URL标题:http://ybzwz.com/article/dopipce.html