深度优先搜索

深度优先搜索:在一个图中,从某一个节点开始访问该图(作为顶点),然后标记该节点为已访问。接着去访问它的邻接未访问的节点,这个过程一直持续,直到遇到一个终点——该节点的所有邻接节点都是已访问。此时,回退到上一个节点,并尝试从这里访问未访问的节点。直到回退到起始点,并且起始点邻接的节点都是已访问。这个时候该算法结束,这个时候该节点所在的连通子图所有的节点都被访问过了。如果还有其他未访问的节点存在,那么该算法必须从其中某一个节点开始,重复上面的过程。直到该图中所有的节点都被访问过了,此时,搜索结束。

深度优先搜索(DFS)的重要应用通常在于检查图的连通性和无环性,当然也能求出一个非连通图的连通分量。

DFS这种策略是能往前多走几步是几步,总是试图走的更远更深。

标记这项工作需要额外的空间来做,否则原来的图就会被破坏。一般是用一个数组来做的。下面给出深度优先搜索的C++实现代码。(深度优先搜索邻接矩阵

// 深度优先搜索(DFS).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <vector>
using namespace std;
class MyGraph
{
public:
	MyGraph();
	~MyGraph();
	void DFS(int start);
	int print(int i, int j);
private:
	int v, e;		//图的顶点数和边数
	vector<vector<int>> matrix;		//邻接矩阵
	vector<int> flag;	//标记数组
};

MyGraph::MyGraph()
{
	cout << "请输入图的顶点数目:\n";
	cin >> this->v;
	cout << "请输入图的边数目:\n";
	cin >> this->e;
	vector<int> temp(this->v);		//用来构造matrix用的
	for (int i = 0; i < this->v; i++)
	{
		this->matrix.push_back(temp);		
	}
	for (int i = 0; i < this->v; i++)	
	{
		this->flag.push_back(0);	//初始标记数组的内容为0
	}
	
	int m, n;
	for (int i = 0; i < this->e; i++)
	{
		cout << "请输入第" << i << "条边的起始点和终点:\n";
		cin >> m >> n;
		this->matrix[m][n] = 1;		//有边用1记录
		this->matrix[n][m] = 1;
	}
}

MyGraph::~MyGraph()
{

}

void MyGraph::DFS(int start)
{
	this->flag[start] = 1;		//用1表示访问过了
	cout << start << '\t';		//此处深度优先搜索只是做了个输出
	for (int i = 0; i < this->v; i++)
	{
		//未标记并且到i这个顶点有边
		if (!flag[i] && this->matrix[start][i] == 1)	
		{
			this->DFS(i);	//从i这个顶点做深度优先搜索
		}
	}
}

int MyGraph::print(int i, int j)	//这个接口函数和深度优先搜索无关
{
	return this->matrix[i][j];
}

int main()
{
	MyGraph graph;
	cout << "深度优先搜索结果:\n";
	graph.DFS(0);
	cout << endl;
	system("pause");
}

对于深度优先搜索的分析依赖于具体的实现,如果图是邻接矩阵存储的,那么时间复杂度是O(v²);如果图是邻接表存储的,那么时间复杂度是O(v+e)。

posted @ 2018-08-25 20:37  zy010101  阅读(157)  评论(0编辑  收藏  举报