2022.7.11 dfs深度优先搜索+数组模拟栈

一、深度优先搜索

1.理解 深度优先搜索,是一种自上而下的搜索方式,蕴含着递归的思想,在模板题中,需要注意的是:

    1.注意递归的结束标志,从第0位开始搜索,在位数u==n时代表着结束,而不是u==n-1时结束。

    2.在搜索完一位后,递归搜索下一位时,要对数组进行还原,还原到以前的样子,在排列中即为book[i]要重新定义为false,代表没有用过该数字。

    3.含义:

       book[i]: 标记使用过的数

       a[i]:存储排序结果

模板如下:

#include <iostream>
using namespace std;
const int N=10;
int a[N];
int book[N];
int n;
void dfs(int u){
    if(u==n){
        for(int i=0;i<n;i++) cout <<a[i]<<" ";
        cout <<endl;
    }
    else {
        for(int i=1;i<=n;i++){
            if(!book[i]){
                a[u]=i;
                book[i]=true;
                dfs(u+1);
                book[i]=false;//重新标记为false,代表没有用过,进行下一次循环
            }
        }
    }
}
int main(){
    cin>>n;
    dfs(0);
}

2.n-皇后问题

思路和上题类似,同样是利用dfs,在这里是对它的每一行的列进行搜索,判断每一列、每一行、以及对角线上是否有重复元素。

含义:

      a[N][N]:代表棋盘

      rol[N]  d[N]  ud[N]:分别用来标记列、对角线、反对角线上是否有元素出现

#include <iostream>
#include <cstring>
using namespace std;
const int N=12;
int n;
char a[N][N];//作为棋盘进行标记
bool rol[N],d[N],ud[N];
void dfs(int u){
    if(u>=n) {
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++) cout <<a[i][j];
            cout <<endl;
        }
        cout <<endl;
        return;
    }
    else {
        for(int i=1;i<=n;i++){//u代表行,i代表列
            if(!rol[i]&&!d[n-i+u]&&!d[i+u]){
                a[u][i]='Q';
                rol[i]=d[n+i-u]=d[i+u]=true;
                dfs(u+1);
                rol[i]=d[n+i-u]=d[i+u]=false;
                a[u][i]='.';
            }
        }
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=0;j<n;j++){
            a[i][j]='.';
        }
    }
    dfs(1);
}

3.栈

是一种比较好理解的数据结构,遵循 ”先进后出“ 的原则,仅需要一个数组以及指向栈顶的指针tt即可实现。栈可以用数组模拟,同时也有其专门的头文件和实现一系列操作的函数。

用数组模拟的代码如下:

#include <iostream>
#include <string>
using namespace std;
const int N=1e5+10;
int stk[N],tt;
int main(){
    int n;
    cin>>n;
    while(n--){
        string ch;
        cin>>ch;
        if(ch=="push"){
            int x;
            cin>>x;
            stk[++tt]=x;
        }
        else if(ch=="pop"){
            tt--;
        }
        else if(ch=="empty"){
            if(tt==0) cout <<"YES"<<endl;
            else cout <<"NO"<<endl;
        }
        else {
            cout <<stk[tt]<<endl;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值