全排列算法

本文介绍了一种递归全排列算法的实现逻辑,并通过分治法逐步分解问题规模,直至求解出所有可能的排列组合。文章还提供了核心代码示例。

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

全排列算法

全排列算法是有多种算法,目前我们只考虑其中的一种,如果后续遇到了,我也会继续更新我的博客。

递归算法核心

分治法全排列实现逻辑

定义集合 R = {r1,r2,r3 … rn} 表示含有n个元素的集合,也就是我们需要排列的数据
定义集合Ri = R - {ri}; Ri表示n个元素中去掉ri的元素的集合
定义含有X集合中所有元素的全排列Perm(X)
定义N(Perm(X))表示集合X的全排列的数目
定义元素rPerm(X)表示以r开头的X中所有元素的全排列
比如 r = 2 X = { 1,3}
rPerm(X) = 2Perm(X)
N(rPerm(X)) = N(Perm(X)) 以2开头,后续字符串是集合X的全排列 rPerm(X)在这里全排列的数目 与Perm(X)的数目是一致的

定义全排列

if n == 1
   r1Perm(R1)  R1为空 r1的全排列是r1  N(Perm(X)) = 1;
if n > 1
   Perm(R) = r1Perm(R1) + r2Perm(R2) + r3Perm(R3) + ... + rnPerm(Rn)   Rn都是n-1
   这里将全排列的问题规模已经缩减到了n-1的规模
   然后继续对Perm(R1),Perm(R2),Perm(R3)... Perm(Rn)进行问题分解,直到问题规模变成1

如果你被上方的数学算法所绕晕了,那么换一种直观的数据表达方式
如果R = { 1,2,3,4}
Perm(R) = 1Perm(R1) + 2Perm(R2) + 3Perm(R3) + 4Perm(R4)
这里我们将定义Xi = Ri 这个只是问题规模缩小后,无法再使用R表示当前的集合
X1 = {2,3,4}
X2 = {1, 3, 4}
X3 = {1, 2, 4}
X4 = {1, 2, 3}
这里我们定义Xii =(X- xi) - xii 表示去掉元素xi和xii的元素
Perm(R1) = 2Perm(X11) + 3Perm(X12) + 4Perm(13)
X11 = {3,4}
X12 = {2,4}
X12 = {2,3}
//全排列输出
Perm(X11) = 3Perm(X111) + 4Perm(X112) = {1,2,3,4} + {1,2,4,3}
N(PermX11) = 2

如果对上述内容存在疑问
这里写图片描述
我们之前的描述是针对这副图的抽象。
在我们进行Perm(X)的全排列时,我们保持一个元素不变,求Perm(X-1)规模的全排列。

核心代码如下

void FullPermutationDivideConquerMethod::permutation(char *t, int start, int len) {
    if (start == len -1) {
        std::cout << t << std::endl;
        times++;
        return;
    }
    if (len < 0) {
        std::cerr << "the len is illegal" << std::endl;
        return;
    }
    for (int i = start; i < len; i++) { //广度遍历,将所有元素与第一个元素交换
        Tools::swap(t, i, start, len);
        permutation(t, start+1, len);  //将问题规模缩小
        Tools::swap(t, i, start, len);
    }
}
调用 
permutation(t, 0, len);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值