搜索--DFS--基础

本文介绍了深度优先搜索(DFS)算法的基本原理,探讨了其在排列数字和n-皇后问题中的应用,重点讲解了一维和二维枚举方法如何通过DFS实现解决方案。

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

简介

深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(n!)。

原理

为了求得问题的解,先选择某一种可能情况向前探索;
在探索过程中,一旦发现原来的选择是错误的,就退回一步重新选择,继续向前探索;
如此反复进行,直至得到解或证明无解。

操作

不断向前搜索,若满足则输出,不满足,向后回溯,再向下一个元素点搜索

应用

842. 排列数字

题目

分析

一维枚举

本题,就相当于枚举每一个结果,从第一个位置到最后一个位置,首先想到DFS,因为dfs另一个含义就是爆搜,本题想到每一元素只能选一个,所以枚举每一个位置的元素可能是谁,依次向后拓展搜索,当超过了总位置数,则打印结果,否则继续拓展。

代码

#include <iostream>

using namespace std;

const int N = 10;

int n;

int q[N];
bool st[N];

void dfs(int u)
{
    if(u > n)
    {
        for(int i = 1; i <= n; i ++) printf("%d ", q[i]);
        puts("");
    }
    
    // 遍历每一个剩余的数字
    for(int i = 1; i <= n; i ++)
    {
        if(!st[i])
        {
            // 在第u位置上使用i 
            q[u] = i;
            st[i] = true;
            
            //搜索下一个位置 
            dfs(u + 1);
            
            // 恢复现场
            st[i] = false;
            q[u] = 0;
            
        }
    }    
}


int main()
{
    scanf("%d", &n);
    
    dfs(1);
    
    return 0;
}

843. n-皇后问题

题目

在这里插入图片描述

分析

二维枚举

本题,就相当于枚举每一个结果,从第一行到最后一行,首先想到DFS,因为dfs另一个含义就是爆搜,本题想到每一行只能选一个,所以枚举第一行的每一个列元素,依次向下行拓展搜索,当超过了总行数,则打印矩阵,否则继续拓展。

代码

// n-皇后问题
#include <iostream>
#include <cstring>
#include <stdio.h>


using namespace std;

const int N = 15;

int n;
char g[N][N];
bool col[N], dg[2 * N + 1], udg[2 * N + 1];

void dfs(int u)
{
	// 遍历到最后一行 
	if(u > n)
	{
		// 初始化棋盘
    	for(int i = 1; i <= n;  i ++)
    	{
    		for(int j = 1; j <= n; j ++)
    		{
    		  //  g[i][j] = '.'; 
    		    printf("%c", g[i][j]);
    		}
    		
    		printf("\n");
        }
        cout << endl;
	}
	
	// 当前行 
	int x = u;
	
	// 枚举当前行的每一个列元素 
	for(int i = 1; i <= n; i ++)
	{
		if(col[i] != true && udg[i + u] != true && dg[i - u + n] != true)
		{
			// 使用当前位置 
			col[i] = udg[i + u] = dg[i - u + n] = true;
			g[u][i] = 'Q';
			// 搜索下一行 
            dfs(u + 1);
            // 恢复现场 
            col[i] = udg[i + u] = dg[i - u + n] = false;
            g[u][i] = '.';
		}
	}
}



int main()
{
	cin >> n;

	
	// 初始化棋盘
	for(int i = 1; i <= n;  i ++)
		for(int j = 1; j <= n; j ++)
		{
		    g[i][j] = '.'; 
		  //  printf("%c", g[i][j]);
		}
		
	dfs(1);
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wbzuo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值