搜索(dfs)

文章介绍了深度优先遍历(DFS)的概念,以及如何使用DFS解决全排列问题。提供了C++代码示例,展示了如何生成1到n的所有不重复排列。同时提到了next_permutation和prev_permutation函数在生成排列时的作用。
摘要由CSDN通过智能技术生成

深度优先遍历(DFS)

就是要走就先走完一整条路,再返回去走别的可能的路。
1.访问指定的起始顶点
2.若当前访问的顶点的邻接顶点有未被访问的(通过标记数组实现),则任选一个去访问;反之,退回到最近访问过的顶点;直到与起始点相通的全部顶点访问完毕
3.若图中还有顶点未被访问,再选其中一个顶点作为起始顶点进行访问,进行步骤2;反之,遍历结束

想法

1.判断当前状态是否满足题目需要,满足则进行保存,比较,输出等操作
2.判断当前状态是否合法(当前状态是否满足题目要求,或者数组是否越界),满足继续执行否则回到上次调用
3.往下走一层,递归调用dfs()

全排列函数

next_permutation(start,end):求出当前排列的下一个排列
prev_permutation(start,end)求出当前排列的上一个排列
当前序列不存在下一个排列时函数返回false,否则返回true

#include <bits/stdc++.h>

using namespace std;

int arr[1000];
int main()
{
    int n;
    cin>>n;
    for(int i = 0; i < n; i++) arr[i] = i + 1;
    //采用do——while循环来输出初始的序列
     do{
        for(int i = 0; i < n; i++) cout << arr[i] << " ";
        cout << endl;
     }while(next_permutation(arr, arr+n));
     return 0;
}

模板:
1:首先将遍历过的进行标记
2:将当前状态赋值
3:递归搜索
4:回到当前状态以后,之前的标记要消除

#include <bits/stdc++.h>
using namespace std;

int arr[1000];
int book[1000]; //用来表示此数字有没有被用过,初始化为0表示没用过
int n;
void dfs(int step)//step表示当前处于第step个盒子
{
    if(step==n+1) //先写退出条件,让答案输出
    {
        for(int i  = 1; i <= n; i++) cout<< arr[i] << ' ';
        cout << endl;
        return;  //此题目一定要写,不返回的话会一直搜索下去然后卡死
    }//让它返回到第n个盒子继续处理
    for(int i = 1; i <= n; i++)
    {//遍历盒子如果book[i]显示为0的话表示没用过,可放到盒子里去
        if(!book[i])
        {
            book[i] = 1; //先让他标记为1表示用过了
            arr[step] = i;//放到盒子里去
            dfs(step+1);//继续搜索下一个地方
            book[i] = 0;//消除之前的标记
        }
    }
}
int main()
{
    cin>>n;
    dfs(1);
    return 0;
}

全排列问题

题目描述

按照字典序输出自然数 1 1 1 n n n 所有不重复的排列,即 n n n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

输入格式

一个整数 n n n

输出格式

1 ∼ n 1 \sim n 1n 组成的所有不重复的数字序列,每行一个序列。

每个数字保留 5 5 5 个场宽。

样例 #1

样例输入 #1

3

样例输出 #1

1    2    3
    1    3    2
    2    1    3
    2    3    1
    3    1    2
    3    2    1

提示

1 ≤ n ≤ 9 1 \leq n \leq 9 1n9

#include<bits/stdc++.h>
using namespace std;
int n, pd[100], used[100];
void print()
{
    int i;
    for (i = 1; i <= n; i++)
        printf("%5d", used[i]);
    cout << endl;
}
void dfs(int k)
{
    int i;
    if (k == n)
    {
        print();
        return;
    }
    for (i = 1; i <= n; i++)
    {
        if (!pd[i])
        {
            pd[i] = 1;
            used[k + 1] = i;
            dfs(k + 1);
            pd[i] = 0;
        }
    }
}
int main()
{
    cin >> n;
    dfs(0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冬樱春雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值