搜索

对路径的BFS

岛(BFS)

 

 

 

 

 

 DFS(DFS虽然好写,但图大了容易爆栈)

void DFS(int x,int y){
    if(judge(x,y)==false)
        return;
    inq[x][y]=true;
    DFS(x+1,y);
    DFS(x-1,y);
    DFS(x,y+1);
    DFS(x,y-1);
} 

 

最短路径(BFS)

 

 

 

 

BFS中queue的注意事项

 

queue存的是你push进去的对象的副本,不是原对象。

如果你的原对象是一个数组中的元素,你应该把它们的下标或者指针传进去,这样你在queue中就可以直接修改原数组中的对象了,同时如果你修改了原数组中的对象,你在queue中访问数组中的对象当然也就被修改过了,而不是直接把数组中的元素传进去,这样就产生了两份数据,修改一方,另一边不同步

当然你可以直接创建临时对象(  q.push(Node{x,y,step+1});  )或者像上面那样总是用一个暂时的对象(临时节点Node,每次  q.push(Node);  ),把它们直接放到queue中去,这样的话数据只存在queue里面,对上面遍历图的例子,这样是最合适的

理清楚程序中的内存关系,数据到底存在哪,避免莫名其妙的BUG

 

 

 

 

 

 

对状态的BFS

BFS搜索(跳蚱蜢) - 顿河顿河 - 博客园 (cnblogs.com)

 

//0、用string存状态
string beg = "000000";
string tar = "111111";
struct State { //也可以用pair
        string state;
        int step;
        State(string _state,int _step):state(_state),step(_step){}
};
string Transform(string s, int pos) {
        //这是操作函数
        string ss = s;
        for (int i = 0; i < LEN; i++) {
                if (i == pos)continue;
                ss[i] = (ss[i] == '0') ? '1' : '0';
        }
        return ss;
}
queue<State> q;
set<string> s;  //去重用,防止入队重复元素
int main() {
        s.insert(beg);
        q.push(State{beg, 0});
        while (!q.empty()) {
                State cur = q.front();
                q.pop();
                cout << cur.step << " " << cur.state << endl;//输出的是队列的情况,把所有出现在队列中的元素都输出了
                if (cur.state == tar) { // 1、用string可以直接比较两个状态是否相等
                        cout << "至少需要" << cur.step << "" << endl;
                        return 0;
                }
                for (int i = 0; i < LEN; i++) {
                        string new_string = Transform(cur.state, i);
                        int new_step = cur.step + 1;
                        State new_state = {new_string, new_step};
                        if (s.find(new_string) == s.end()) { //2、string可以用set来去重
                                s.insert(new_string);
                                q.push(new_state);
                        }
                }
        }
        cout << "无解" << endl;

        return 0;
}

 

 

 

排列的输出(DFS和回溯)

bool isv[10010];
int n;
//int arr[10010]={1,5,36,7,88};
int permutation[10010]; void print(int m) { for(int i=1;i<m;i++) { cout<<permutation[i]; } cout<<endl; } void DFS(int i) { if(i>n) { print(i); return; } for(int j=1;j<=n;j++) { if(isv[j]==0) { //permutation[i]=arr[j];
       permutation[i]=j; isv[j]
=true; DFS(i+1); isv[j]=false; //回溯!!! } } }
int arr[]={1,3,4,2,10,44,23,54};
int perm[sizeof(arr)/sizeof(arr[1])]; 
int sum=0;
void Perm(int begin,int end){
    if(begin==end)
        sum++;
    else{
        for(int i=begin;i<=end;i++){
            swap(arr[begin],arr[i]);
            Perm(begin+1,end);
            swap(arr[begin],arr[i]); //回溯 
        }
    }
}

 

 

bool isv[10010];
int n,sum=0;
int permutation[10010];
void print(int m)
{
    for(int i=1;i<m;i++)
    {
        cout<<permutation[i];
    }
    cout<<endl;
}
void DFS(int i)
{
    if(i>3)
    {
        //print(i);
        sum++;
        return;
    }
    for(int j=1;j<=n;j++)
    {
        if(isv[j]==0)
        {
            permutation[i]=j;
            isv[j]=true;
            DFS(i+1);
            isv[j]=false;
        }
    }
}
int main()
{
    n=10;
    DFS(1);
    cout<<sum;  //720
    return 0;
}

 

posted @ 2022-05-13 16:12  dunhedunhe  阅读(79)  评论(0)    收藏  举报