递归实现排列型枚举

该文章介绍了一种使用递归和回溯法来实现全排列的算法。通过两次for循环,第一次遍历数字并尝试所有可能的选择,第二次循环用于回溯,清除已使用数字的状态,以便生成所有可能的排列。关键在于used[i]数组,用于跟踪每个数字是否已被使用,确保不会重复。

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

递归要实现排列型枚举大概需要用到两次for循环,第一次遍历数字(第一个for循环),确保每个可用的数字我们都能找到,就是在每个深度u上,当前可用的数字都会被尝试一遍,直到找到所有长度为n的排列。

第二次for循环,回溯,每个dfs递归结束后,清空数组state的值,以方便重新利用数字,中间的条件很重要if(!used[i]) 中的 ! 表示逻辑非运算符,用于取反操作,其作用是将 used[i] 的值取反,即如果 used[i]false 则取反后为 true,如果 used[i]true 则取反后为 false

在这段代码中,used[i] 数组用于标记数 i 是否已经被使用过,因此 !used[i] 的意思是数 i 还没有被使用过,也就是说数 i 可以被填入当前位置 u。这个东西自我感觉应该算是点睛之笔。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=10;//常量定义 
int n;//表示要求解n个数的全排列 
int state[N];//存储每个排列的状态 
bool used[N];//表示数字是否已被使用 
void dfs(int u)//边界
{
   if(u>n)//搜索结束,输出排列 
   {
       for(int i=1;i<=n;i++) printf("%d ",state[i]);//输出排列 ,这种皇鞘涑龅谝淮闻帕?
       puts("");//换行 
       return;
   }
   for(int i=1;i<=n;i++)//搜索下一个未被使用的数字 ,这个循环用于全排列,保证其它的排列组合都可以出现 
   if(!used[i])
   {
       state[u]=i;//将该数字加入当前排列中 
       used[i]=true;//标记该数字已被使用 
       dfs(u+1);//搜索下一个位置 
       state[u]=0;//回溯,将该数字从排列中删除 
       used[i]=false;//回溯,标记该数字未被使用 
   }
}
int main()
{
    scanf("%d",&n);//输入要求解的全排列的数字个数 
    dfs(1);//从第一个位置开始搜索 
    return 0;//结束程序 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值