1.深度优先搜索
深度优先搜索(Depth First Search),简称DFS。思想为总是对最近才发现的结点v的出发边进行搜索,指导该结点的所有出发边都被发现为止。
伪码描述:
void DFS(Vertex v)
{
visited[v]=true;
for(v的每个连接点w)
if(!visited[w])
DFS(w);
}
代码如下
其中初始化Create的定义如下:
void create(mgraph * g)
{
int i, j;
int v1, v2;
cout << "请输入顶点数和边数:";
cin >> g->v_num >> g->e_num;
for (i = 0; i < g->v_num; i++)
{
cin >> g->vexs[i];
}
for(i=0;i<g->v_num;i++)
for (j = 0; j < g->v_num; j++)
g->m[i][j] = 0;
for (j = 0; j < g->e_num; j++)
{
cin >> v1 >> v2;
g->m[v1][v2]=g->m[v2][v1]=1;
}
}
- 邻接矩阵表示图
#include<queue>
#define Max_Vertex 10
typedef char Vertex;
typedef int Edge;
struct MGraph
{
int v_num, e_num;
Vertex vexs[Max_Vertex];
Edge M[Max_Vertex][Max_Vertex];
};
/*深度优先搜索*/
using namespace std;
bool visited[Max_Vertex];
void DFS(MGraph G, int i)
{
int j;
visited[i] = true;
cout << G.vexs[i] << " ";
for (int j = 0; j < G.v_num; j++)
{
if (G.M[i][j] == 1&&!visited[j])
DFS(G, j);
}
}
void DFSTraverse(MGraph G)
{
int i; /*开始遍历结点*/
/*开始时设置visited都为0*/
for (i = 0; i < G.v_num; i++)
{
visited[i] = 0;
}
for (i = 0; i < G.v_num; i++)
{
if (!visited[i])
DFS(G, i);
}
}
int main()
{
MGraph G;
Create(&G);
BFS(G);
return 0;
}
运行结果
2. 邻接表表示图
void CreateALGraph(GraphAdjList* G)
{
cout << "请输入顶点数和边数:";
cin >> G->v_num >> G->e_num;
int i, j;
int v1, v2;
for (i = 0; i < G->v_num; i++) //初始化
{
cin >> G->adjList[i].data;
G->adjList[i].firstedge = NULL;
}
for (j = 0; j < G->e_num; j++)
{
cin >> v1 >> v2;
EdgeNode* e1 = new EdgeNode;
e1->adjvex = v2;
e1->next = G->adjList[v1].firstedge;
G->adjList[v1].firstedge = e1;
EdgeNode* e2 = new EdgeNode;
e2->adjvex =v1;
e2->next = G->adjList[v2].firstedge;
G->adjList[v2].firstedge = e2;
}
}
int visited[MaxVextex] = { 0 };
void DFS(GraphAdjList* G,int i)
{
visited[i] = 1;
cout << G->adjList[i].data;
EdgeNode * p = G->adjList[i].firstedge;
while (p)
{
if (!visited[p->adjvex])
DFS(G, p->adjvex);
p = p->next;
}
}
void DFSTraverse(GraphAdjList* G)
{
int i;
for (i = 0; i < G->v_num; i++)
visited[i] = 0;
for (i = 0; i < G->v_num; i++)
{
if (!visited[i])
DFS(G, i);
}
}
int main()
{
GraphAdjList g;
CreateALGraph(&g);
DFSTraverse(&g);
return 0;
}
2.广度优先搜索
广度优先搜索(bread first search,BFS。伪码描述如下
void BFS(Vertex V)
{
visited[v]=true;
Enqueue(V,Q);
while(!Empty(Q))
{
V=Dequeue(Q);
for(V 的每个邻接点 W)
{
if(!visited[W])
{
visited[W]=true;
Enqueue(W,Q);
}
}
}
}
- 邻接矩阵
/*广度优先搜索*/
void BFS(MGraph G)
{
int i, j;
std::queue<int> Q;
for (i = 0; i < G.v_num; i++)
visited[i] = 0;
for (i = 0; i < G.v_num; i++)
{
if (!visited[i])
{
visited[i] = 1;
cout << G.vexs[i] << " ";
Q.push(i);
while (!Q.empty())
{
i = Q.front(); //更新i的值
Q.pop();
for (j = 0; j < G.v_num; j++)
{
if (G.M[i][j] && !visited[j])
{
visited[j] = 1;
cout << G.vexs[j] << " ";
Q.push(j);
}
}
}
}
}
}
2.邻接表
void BFS(GraphAdjList* G)
{
int i;
EdgeNode* p;
std::queue<int> Q;
for (i = 0; i < G->v_num; i++)
visited[i] = 0;
for (i = 0; i < G->v_num; i++)
{
if (!visited[i])
{
visited[i] = 1;
cout << G->adjList[i].data;
Q.push(i);
while (!Q.empty())
{
i = Q.front();
Q.pop();
p = G->adjList[i].firstedge;
while (p)
{
if (!visited[p->adjvex])
{
visited[p->adjvex] = 1;
cout << G->adjList[p->adjvex].data;
Q.push(p->adjvex);
}
p = p->next;
}
}
}
}
}
邻接矩阵和邻接表结果不一样的原因在于,初始化图上的边时,邻接矩阵为顺序输出和顺序查找,而邻接表初始化时,为在头指针处插入,因而在搜索时开始搜索的顶点不一致,导致最终的输出顺序有差异。