c语言回溯法,回溯法 实现 排列组合(C 语言版本)

* 所谓回溯:就是搜索一棵状态树的过程,这个过程类似于图的深度优先

* 搜索(DFS),在搜索的每一步(这里的每一步对应搜索树的第i层)中

* 产生一个正确的解,然后在以后的每一步搜索过程中,都检查其前一步

* 的记录,并且它将有条件的选择以后的每一个搜索状态(即第i+1层的

* 状态节点)。

/*

* 回溯法 实现 排列组合

*

* 所谓回溯:就是搜索一棵状态树的过程,这个过程类似于图的深度优先

* 搜索(DFS),在搜索的每一步(这里的每一步对应搜索树的第i层)中

* 产生一个正确的解,然后在以后的每一步搜索过程中,都检查其前一步

* 的记录,并且它将有条件的选择以后的每一个搜索状态(即第i+1层的

* 状态节点)。

*

* 需掌握的基本算法:

* 排列:就是从n个元素中同时取r个元素的排列,记做P(n,r)。(当r=n时,

* 我们称P(n,n)=n!为全排列) 例如我们有集合OR = {1,2,3,4},那么

* n = |OR| = 4, 且规定r=3, 那么P(4,3)就是:

*

* {1,2,3}; {1,2,4}; {1,3,2}; {1,3,4}; {1,4,2}; {1,4,3};

* {2,1,3}; {2,1,4}; {2,3,1}; {2,3,4}; {2,4,1}; {2,4,3};

* {3,1,2}; {3,1,4}; {3,2,1}; {3,2,4}; {3,4,1}; {3,4,2};

* {4,1,2}; {4,1,3}; {4,2,1}; {4,2,3}; {4,3,1}; {4,3,2}

*

*/

#include

#ifndef MAXN

#define MAXN 5

#endif

static int n = 3, r = 3; /* P(n,r) */

static char used[MAXN]; /* 待排列数据使用标记 */

static char p[MAXN]; /* 解空间 - 保存每次形成的排列结果 */

static char data[] = {'a','b','c'}; /* 待排列组合的数据空间 */

/*

* permute(pos -- 表示在解空间中填写数据的下标位置)

* {

* 如果解空间填写满了 打印解空间当前的排列结果 函数返回

*

* for (i=0; i

* {

* 尝试在这个下标位置填写每一个待排列的数据

* (但这些数据可填写的前提是数据没有被标记为已使用)

*

* 填写后, 把这个下标为i的数据标记为已使用

*

* permute(pos+1); -- 填写解空间中下一个位置

*

* 下标为i的数据已参与了解空间下标pos处的排列

* 取消已使用标记(因为该数据可以在解空间其他下标处使用)

* 继续for循环考察下一个待排列数据

* }

* }

*

* used[i] == 1 - 待排列空间中下标i处的数据已被使用;

* used[i] == 0 - 可以使用待排列空间中下标i处的数据;

*/

void permute(int pos)

{

int i = 0;

if (pos == r)

{

for (i=0; i

printf("%c, ",p[i]);

printf(" ");

return;

}

for (i=0; i

{

if (!used[i])

{

used[i]++;

p[pos] = data[i];

permute(pos+1);

used[i]--;

}

}

}

void main() { permute(0); }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值