DFS(递归+栈) BFS 以及路径记录

DFS:深度优先遍历,深度优先遍历

         两种实现方式:递归和栈。

        递归:从顶点v出发深度遍历图G的算法 
           1 访问v 
           2 依次从顶点v未被访问的邻接点出发深度遍历。 

       栈:

          1访问v

          2将v的邻居节点入栈

          3 将栈的顶部元素出栈访问,同时将其邻居元素入栈,重复3直到栈为空

BFS:宽度优先遍历

         队列实现:

          1访问v

           2将v的邻居节点入队

           3将队的队头元素出队访问,同时将其相邻元素入队,重复3直到队为空

保存路径:vector<int>& 

                 以vector引用形式记录路径,在元素访问的地方push_back();

DFS应用:单词搜索

 

#include<iostream>
#include<vector>
#include<queue>
#include<stack>

using namespace std;

int a[8][8] = {0};
bool visited[8];//全局数组记录访问过的节点

/*
  1 2 3 4 5 6 7 模仿图
                     1
		   /   \
		  2     3
	         /\     /\
	        4--5   6--7
*/

void store_graph()  //邻接矩阵存储图  
{
	/*int i, j;

	for (i = 1; i <= 10; i++)
		for (j = 1; j <= 10; j++)
			cin >> a[i][j];
			*/
	a[1][2] = 1; a[1][3] = 1;
	a[2][1] = 1; a[2][4] = 1; a[2][5] = 1;
	a[3][1] = 1; a[3][6] = 1; a[3][7] = 1;
	a[4][2] = 1; a[4][5] = 1;
	a[5][2] = 1; a[5][4] = 1;
	a[6][3] = 1; a[6][7] = 1;
	a[7][3] = 1; a[7][6] = 1;
}

int Adj(int x)   //求邻接点  
{
	for (int i = 1; i <= 7; i++)
		if (a[x][i] == 1 && visited[i] == false)
			return i;
	return 0;
}

void dfs(int v,vector<int>&path)  //深度遍历顶点  
{
	cout << v << " ";  //访问顶点v 
	path.push_back(v);
	visited[v] = true;

	int adj = Adj(v);
	while (adj != 0)
	{
		if (visited[adj] == false)//先递归第一个邻接点,在递归第二个邻接点。。。
			dfs(adj,path);      //递归调用是实现深度遍历的关键所在  
		adj = Adj(v);//v的上一个邻接点访问到已经访问的,则找下一个邻接点
	}
}

//将顶部节点所有未被访问的“邻居”(即“一层邻居节点”)踹入栈中“待用”
//然后围绕顶部节点猛攻,每个节点被访问后被踹出
void dfs_stack(int v,vector<int>&path)
{
	stack<int>s;
	cout << v << " ";
	path.push_back(v);
	visited[v] = true;
	int temp = Adj(v);
	while (temp != 0)
	{
		s.push(temp);
		visited[temp] = true;
	    temp = Adj(v);
	}//保存与头一个点相连接的所有点
	while (!s.empty())
	{
		int top = s.top();
		visited[top] = true;
		cout << top << " ";
		path.push_back(top);
		s.pop();

		int adj = Adj(top);//将刚弹出栈顶的元素的所有邻接点入栈
		while(adj!=0)//刚弹出来的节点邻接点在入栈在上方,先访问,深度优先
		{
			s.push(adj);
			visited[adj] = true;
			adj = Adj(top);
		}
	}
}


void bfs(int v,vector<int>&path)//宽度遍历顶点
{
	cout << v << " ";//访问初始节点
	path.push_back(v);
	visited[v] = true;

	int adj;
	queue<int>q;
	q.push(v);
	int temp;
	while (!q.empty())
	{
		temp = q.front();
		q.pop();
		adj = Adj(temp);//将队头节点入队
		while (adj != 0)
		{
			if (visited[adj] == false)
			{
				cout << adj << " ";
				path.push_back(adj);
				visited[adj] = true;
				q.push(adj);
			}
			adj = Adj(temp);
		}

	}
}

void print_path(vector<int>path)
{
	for (auto v : path)
		cout << v << " ";
	cout << endl;
}

int main()
{
	cout << "初始化图:" << endl;
	store_graph();

	memset(visited, false, sizeof(visited));
	cout << "dfs递归遍历结果:" << endl;
	vector<int>path1;
	dfs(1, path1);
	cout << endl;
	print_path(path1);

	memset(visited, false, sizeof(visited));
	cout << "dfs栈结构遍历结果:" << endl;
	vector<int>path2;
	dfs_stack(1, path2);
	cout << endl;
	print_path(path2);
	

	memset(visited, false, sizeof(visited));
	cout << endl;
	cout << "bfs队列结构遍历结果:" << endl;
	vector<int>path3;
	bfs(1,path3);
	cout << endl;
	print_path(path3);

	return 0;
}

 

运行结果:

力扣79:单词搜索

class Solution {
public:

    bool exist(vector<vector<char>>& board, string word) {
        vector<vector<bool>> is_visited(board.size(), vector<bool>(board[0].size(),false));
        for(int i = 0;i<board.size();++i)
        {  
            for(int j = 0;j<board[0].size();++j)
            {
                if(dfs_exist(board,word,is_visited,0,i,j))
                    return true;
            }
        }
        return false;    
    }
    
    bool dfs_exist(vector<vector<char>>& board,string&word,vector<vector<bool> >&is_visited,int start_index,int x,int y)
    {
    
        if(start_index == word.size())
            return true;
        if(x<0||x>=board.size()||y<0||y>=board[0].size()||board[x][y]!=word[start_index]||is_visited[x][y])
            return false;
        is_visited[x][y] = true;
        
        bool ret = (dfs_exist(board,word,is_visited,start_index+1,x+1,y)||
            dfs_exist(board,word,is_visited,start_index+1,x-1,y)||
            dfs_exist(board,word,is_visited,start_index+1,x,y+1)||
            dfs_exist(board,word,is_visited,start_index+1,x,y-1));
         //当我们把ij位置的所有都找完之后,会到这一步,不管成功与否,我们都需要
        //把ij这个位置的可走信息变成false(可走),因为这一步之后,会回溯至上一个位置的
        //另一种路线,而另一种路线是可以走ij这个位置的。
        is_visited[x][y] = false;//回溯,当前节点未访问
        
        return ret;
    }
};

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值