栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

顺序全排列 简单回溯算法详解 [c++]

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

顺序全排列 简单回溯算法详解 [c++]

顺序全排列 简单回溯

目录
  • 顺序全排列 简单回溯
    • 例题
    • 题解思路
    • 解释①
    • 尾言

例题

告诉你一个按顺序排列的数字,例如(1,3),(2,6)等,请列出他们的全排列结果。

输入: start = 1 end = 3

输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

题解思路

如果数字比较少,可以用嵌套for循环解题,但是for循环消耗的空间和时间都比较多,不建议使用,所以就需要用到解决全排列问题最常用的算法思路:回溯算法;

需要用到:

used[maxx]用于判断某个数字是否已经被用过;

p[maxx] 用于存放排列的结果;

回溯算法的步骤是 使用数据 -> 输出结果 -> 重置空间 ->继续使用,所以used[paxx]就可以发挥重置的作用,使用后讲其变为flase就相当于重置/退回;

回溯中需要用到递归,index + 1 ,例题中,就相当于先取1为首之后,inedx = 1+1 =2 ,used[2] = true,第二个绑定为2,使用结束后,used[2]重置为flase,inedx = 2+1 =3,used[3] = true,第三个绑定为3,used[3] 重置为false,第一个排列结果就是[1, 2, 3];

根据这个思路就可以写出代码:

#include 
using namespace std;
const int maxx = 13;
int p[maxx];   // 存放排列结果
bool used[maxx] = { false };  // 判断数字是否用过,且用于回溯(重置)
int sstart,send; // 开始数字和结束数字  解释①

void backk(int index){   // index 为开始数字
    if(index == send + 1){     //设置出口, 如果已经排列到了end+1,说明已经不用排列了,输出排列的组合
        for(int i = sstart;i <= send;i++){
            cout << p[i] << " ";
        }
        cout << endl;
        return ; // 退出
    }
    
    for(int i = sstart;i <= send;i++){
        if(!used[i]){  // 如果used[i] = flase,该数字没有用过的话,就开始递归
            p[index] = i;   // 把数字i放进排列数组中
            used[i] = true;  // 标记已经使用
            backk(index + 1); // 进入递归,送start循环到end
            used[i] = false; // 重置该数字
        }
    }
}

int main(){
    cout << "start: ";
    cin >> sstart;
    cout << "end: ";
    cin >> send;
    backk(sstart);
    return 0;
}

了解完顺序全排列之后,可以接着看看乱序全排列
点击查看 乱序全排列,C++实现

解释①

用sstart和send的原因是在vs中,start和end会和其定义的全局变量发生冲突,产生变量不明确的报错。


尾言

感谢您的阅读!
如果文章有错误请留言指出,谢谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/876343.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号