全排列C语言

全排列就是将n数字按照不同的顺序排列出来,比如给定3个数字,1 2 3,那这三个数字全排列就是

1 2 3 

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

排列方法就是先定1个位置的数字,再定下一个,再定下一个就行,比如 1 2 3三个数:

A:先定数字1

1 ﹉ ﹉,那么第二个位置数字只能是2或者3,接下来先定2或3都行

1 2 ﹉那么最后一个数字就只能是3。

B:再回溯

上个例子,定了1 2 3,回溯第二步就是只选择了1

1 ﹉ ﹉,并且2已经选择过了,所以只能选择3,那么就是 1 3 ﹉,第三个数就只能是2,序列就是1 3 2。以此类推就行。

C代码部分:

因此我们需要一个数组来记录该数字是否访问。

就拿四个数字

1 2 3 4 ,递归的大体框架

﹉﹉﹉﹉﹉

void dfs(int step){

    if(到达目的地){

            输出解

      }

     返回

合理的剪枝操作:

 for(int i = 1; i <=枚举数;i++){

      if(满足条件){

          更新状态位;

          dfs(step+1);

        恢复状态位;

       }

   }

}

﹉﹉﹉﹉

具体代码:

﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉

int  k;k是数字个数

int i;

int a[10];//存储数字的数组

int used[10];//访问记录数组

void  dfs(int step){    //step就是排列的数字

      if(step==k){

           for(i=0;i <k;i++){

               printf("%d ", a[i]);   //输出

           }

          printf("\n");

          return;

      }

     for(i=0;i <k;i++){

          if (used [i]==0){

             used[i]= 1;

            a[step] = i;

            dfs (step+1);//递归

            used[i] = 0; // 回溯

          }

     }

}

﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉﹉

这就可以完成全排列,

同时也可以从5个数字排列4个数字使用俩个dfs函数即可,

同时添加一个数组用来记录5个数字选了哪4个数字全排列

然后用这个函数全排列4个。

同时选的四个也需要一个数组来记录是否用过,避免重复。

可以看一下

#include <stdio.h>

 

#define N 5 // 总共的数字个数

#define K 4 // 选出的数字个数

 

int nums[N] = {1, 2, 3, 4, 5}; // 初始数据

int selected[K]; // 存储选出的 4 个数字

int used[N] = {0}; // 记录哪些数被使用

int perm[K]; // 存储排列

int used_perm[K] = {0}; // 记录排列中哪些数已使用

// 递归生成排列

int k=0;

void permute(int depth) {

    if (depth == K) { // 当排列长度达到 K

        for (int i = 0; i < K; i++) {

            printf("%d ", perm[i]);

        }

        k++;

        printf("\n");

        return;

    }

 

    for (int i = 0; i < K; i++) {

        if (!used_perm[i]) { // 确保元素不重复使用

            used_perm[i] = 1;

            perm[depth] = selected[i];

            permute(depth + 1);

            used_perm[i] = 0; // 回溯

        }

    }

}

 

// 递归生成组合

void combine(int start, int depth) {

    if (depth == K) { // 选满 4 个数后,进行全排列

        for (int i = 0; i < K; i++) {

            used_perm[i] = 0; // 初始化排列使用标记

        }

        permute(0); // 对当前选出的 4 个数进行全排列

        return;

    }

 

    for (int i = start; i < N; i++) {

        if (!used[i]) {

            used[i] = 1;

            selected[depth] = nums[i];

            combine(i + 1, depth + 1);

            used[i] = 0; // 回溯

        }

    }

}

 

int main() {

    combine(0, 0); // 生成所有 4 个数的组合,并对每个组合求全排列

    printf("%d",k);

    return 0;

}

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值