描述
从根节点开始的递归深度优先搜索与树的前序遍历(preorder traversal)类似,是前序遍历的推广。从某个顶点V开始处理,然后递归地遍历所有与顶点V邻接的且没有被访问过的顶点。算法的基本思想如下:
假设图G初态为所有顶点未被访问(visited[i]=false),从G中任选一顶点vi :
- 从该顶点vi出发,首先访问vi,,置visited [vi ]=true;
- 然后依次搜索vi的每一个邻接点vj ;
- 若vj未被访问过,则以vj为新的初始出发点,重复1;若vj已被访问过,则返回到vi另一个邻接点,重复3
- 如果经过1、2、3后,图中仍有未被访问的顶点,再从中任选一顶点,重复1、2、3,直至所有顶点都被访问过,遍历结束。
如上图所示,左边的是深度优先搜索,右边是广度优先搜索。深度优先搜索是从顶点到顶点,对于给定的顶点尝试过每一种可能后,就退到上一个顶点来尝试下一个顶点。宽度优先搜索则是尝试一个顶点的所有可能之后,才访问下一个顶点。
深度优先搜索的算法模板:
void Dfs(Vertex V)
{
Visited[v] = True;
for each W adjacent to V
if(!Visited[W])
Dfs(W);
}
测试代码
(图的存储是邻接表的深度优先搜索)
#include <iostream>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#define Max_Vertex_Num 100 //最大顶点数
typedef char VertexType; //顶点数类型定义
typedef int EdgeType; //边类型定义
typedef struct EdgeNode
{
int adjvex; // 该边所指的顶点的位置
EdgeType weight; //该边的权值
struct EdgeNode *NextEdge; //指向下一条边的指针
}EdgeNode;
typedef struct VertexNode
{
VertexType data; // 顶点信息
EdgeNode *firstEdge; //指向第一条依附该顶点的边表头指针
}VertexNode, AdjList[Max_Vertex_Num];
typedef struct
{
AdjList adjList;
int EdgeNum; // 图的当前边数
int VertexNum; //图的当前顶点数
bool visited[Max_Vertex_Num]; //顶点是否被访问过
}ALGraph;
// 返回顶点v的位置
int LocateVertex(ALGraph *G, VertexType v)
{
int i = 0;
for(i = 0; v != G->adjList[i].data && i < G->VertexNum; i ++);
if(i >= G->VertexNum)
return -1;
return i;
}
//增加节点
void AddVertex(ALGraph *G)
{
cout << "input vertex number" << endl;
cin >> G->VertexNum;
cout << "input vertex value" << endl;
for(int i = 0; i < G->VertexNum; i++)
{
cin >> G->adjList[i].data;
G->adjList[i].firstEdge = NULL;
}
}
//增加边表
void AddEdge(ALGraph *G)
{
cout << "input edge number" << endl;
cin >> G->EdgeNum ;
VertexType V1, V2;
cout << "input two vertex" << endl;
for(int k = 0; k < G->EdgeNum; k ++)
{
cin >> V1 >> V2;
int i = LocateVertex(G,V1);
int j = LocateVertex(G,V2);
EdgeNode *pe1 = (EdgeNode *)malloc(sizeof(EdgeNode));
pe1->adjvex = i;
pe1->NextEdge = G->adjList[j].firstEdge;
G->adjList[j].firstEdge = pe1;
EdgeNode *pe2 = (EdgeNode *)malloc(sizeof(EdgeNode));
pe2->adjvex = j;
pe2->NextEdge = G->adjList[i].firstEdge;
G->adjList[i].firstEdge = pe2;
}
}
void CreatALGraph(ALGraph *G)
{
AddVertex(G);
AddEdge(G);
}
void PrintALGrap(ALGraph *G)
{
EdgeNode *pe;
cout << "编号 顶点 邻点编号" << endl;
for(int i = 0; i < G->VertexNum; i ++)
{
cout << " " << i << " " << G->adjList[i].data << " ";
for(pe = G->adjList[i].firstEdge; pe; pe = pe->NextEdge)
cout << pe->adjvex << " ";
cout << endl;
}
}
// 深度搜索
void DFS(ALGraph *G, int i)
{
EdgeNode *pe;
G->visited[i] = true;
cout << G->adjList[i].data << " "; //打印顶点
pe = G->adjList[i].firstEdge;
while(pe)
{
if(!G->visited[pe->adjvex])
DFS(G,pe->adjvex);
pe = pe->NextEdge;
}
}
void DFS_Traverse(ALGraph *G)
{
int i = 0;
for(i = 0; i < G->VertexNum; i ++)
G->visited[i] = 0;
for(i = 0; i < G->VertexNum; i ++)
if(!G->visited[i])
DFS(G,i);
}
int main()
{
ALGraph GL;
CreatALGraph(&GL);
PrintALGrap(&GL);
DFS_Traverse(&GL);
}
(图的存储方式邻接矩阵的深度优先搜索)
#include <iostream>
using namespace std;
const int VERTEX_NUM = 20; // 顶点的最大数
typedef int graph_weight_t; // 边的权值类型 可以为 int float double
typedef struct SArc
{
graph_weight_t Weight; // 权值
}AdjMatrix[VERTEX_NUM][VERTEX_NUM]; // 邻接矩阵
typedef struct SGraph
{
int iVertexNum; // 顶点数
int iArcNum; // 边数
int aVertex[VERTEX_NUM]; // 顶点向量
AdjMatrix mArcs; //邻接矩阵
bool visited[VERTEX_NUM];
}Graph;
void IintGraph(Graph &graph)
{
//graph = (pGraph)malloc(sizeof(Graph));
graph.iVertexNum = 0;
graph.iArcNum = 0;
for(int i = 0; i < VERTEX_NUM; i++)
graph.aVertex[i] = 0;
for(int i = 0; i < VERTEX_NUM; i ++)
for(int j= 0; j < VERTEX_NUM; j ++)
graph.mArcs[i][j].Weight = 0;
}
void Add_Vertex(Graph &graph)
{
cout << "Add Vertex" << endl;
cout << "Input vertex number:";
cin >> graph.iVertexNum;
cout << "Input vertex value:";
for(int i = 0; i < graph.iVertexNum; i ++)
cin >> graph.aVertex[i];
}
int Locat_vertex(Graph &graph, int vertex)
{
for(int i = 0; i < graph.iVertexNum; i ++)
{
if(graph.aVertex[i] == vertex)
return i;
}
return -1;
}
void Add_Arcs(Graph &graph)
{
cout << "Add Arcs" << endl;
cout << "input arcs numbers:";
cin >> graph.iArcNum;
int iFirst = 0;
int iSecond = 0;
int iRow = 0;
int iCol = 0;
graph_weight_t iWeight = 0;
for(int i = 0; i < graph.iArcNum; i ++)
{
cout << "Input two Arc and Weight(ex. 1 2 32)" << endl;
cin >> iFirst >> iSecond >> iWeight;
iRow = Locat_vertex(graph, iFirst);
iCol = Locat_vertex(graph, iSecond);
graph.mArcs[iRow][iCol].Weight = iWeight;
graph.mArcs[iCol][iRow].Weight = iWeight;
}
}
void Creat_Graph(Graph &graph)
{
cout << "Creat Graph" << endl;
Add_Vertex(graph);
Add_Arcs(graph);
}
void Show_Graph(Graph &graph)
{
cout << "show the graph represented by adjmatrix "<<endl;
for(int row = 0; row < graph.iVertexNum; row ++)
{
for(int col =0; col < graph.iVertexNum; col ++)
{
cout << graph.mArcs[row][col].Weight << "\t";
}
cout << endl;
}
}
void DFS(Graph &graph, int i)
{
graph.visited[i] = true;
cout << graph.aVertex[i] << endl;
for(int j = 0; j < graph.iVertexNum; j ++)
{
if(graph.mArcs[i][j].Weight==1&&!graph.visited[j])
DFS(graph,j);
}
}
void DFS_traversal(Graph &graph)
{
for(int i = 0; i < graph.iVertexNum; i ++)
graph.visited[i] = 0;
for(int j = 0; j < graph.iVertexNum; j ++)
{
if(!graph.visited[j])
DFS(graph,j);
}
}
int main()
{
Graph graph;
IintGraph(graph);
Creat_Graph(graph);
Show_Graph(graph);
DFS_traversal(graph);
}
时间: 2024-10-07 18:12:35