1.DFS(深度优先遍历)
DFS:假设图g的每一个节点都未被访问过,从顶点V出发依次访问它的临接顶点W,若W无临接节点则返回V并访问下一个临接节点W2。直到所有节点都被访问到。
a.临接表的DFS
思路:在有向图临接表中,我们知道每一个顶点V后都依次连着它的临接顶点,那我们只要依次访问就好,并用递归来实现遍历全部。
//邻接表实现图的建立和DFS
#include<iostream>
using namespace std;
typedef char VertexType;
int Visited[1000] = {0};//用来判断顶点是否已经访问过。
struct EdgeNode
{
int Adjv;
struct EdgeNode * next;
};
struct VertexNode
{
VertexType Vertex;
EdgeNode * first;
};
struct ALGraph
{
VertexNode adjlist[100];
int ver_num, edge_num;
};
ALGraph * CreateALGraph()
{
ALGraph * g = new ALGraph;
EdgeNode * edge;
int i, j, k;
cout << "请输入顶点数和边数" << endl;
cin >> g->ver_num >> g->edge_num;
cout << "请输入顶点信息" << endl;
for (i = 0; i < g->ver_num; i++)
{
cin >> g->adjlist[i].Vertex;//输入顶点信息
g->adjlist[i].first = NULL;
}
cout << "请输入边的信息" << endl;
for (k = 0; k < g->edge_num; k++)
{
cin >> i >> j;//输入相连两节点的序号
edge = new EdgeNode;
edge->Adjv = j;
EdgeNode * h;
EdgeNode * t;
// cout<<g->adjlist[i].first<<endl;;
if( g->adjlist[i].first == NULL )
{
g->adjlist[i].first = t = h = edge;
h->next = NULL;
}
else
{
while( t->next != NULL )
{
t = t->next;
}
// cout<<t->Adjv<<endl;
t->next = edge;
edge->next = NULL;
}
// g->adjlist[i].first = edge;
}
return g;
}
void DFS( ALGraph * g , int i )//深度遍历算法
{
EdgeNode * w;
cout<<" 已访问的节点:"<<g->adjlist[i].Vertex<<endl;
Visited[i] = 1;
for( w = g->adjlist[i].first ; w ; w = w->next )
if( !Visited[ w->Adjv ] )
DFS( g , w->Adjv );
}
int main()
{
ALGraph * g;
g = CreateALGraph();
for (int i = 0; i < g->ver_num; i++)
{
cout << g->adjlist[i].Vertex << " ";
for (EdgeNode * p = g->adjlist[i].first; p != NULL; p = p->next)
{
cout << p->Adjv << " ";
}
cout << endl;
}
DFS(g,0);
return 0;
}
b.临接矩阵的DFS
思路:我这里没有用递归,而是使用了栈,在临接矩阵中去遍历顶点I的临接节点j,若Edges[i][j]==1则把i入栈并且重新遍历,直到栈为空且J遍历完毕。
#include<iostream>
#include"stack.h"
#define MAX 100;
#define MINFINITY 65535;
using namespace std;
typedef char VertexType;//顶点为char型
typedef int EdgeType;//边的权重为int型
int Visited[]={0};
struct MGraph {
VertexType Vertices[100];//顶点表
EdgeType Edges[100][100];//邻接矩阵
int vertex_num; //顶点数
int edge_num; //边数
};
MGraph * CreateMGraph()
{
MGraph *g = new MGraph;
int i, j, k, w;
cout << "请输入顶点数和边数(格式为:顶点数 边数)" << endl;
cin >> g->vertex_num >> g->edge_num;
cout << "请输入顶点信息" << endl;
for (i = 0; i < g->vertex_num; i++)
{
cin >> g->Vertices[i];
}
for (i = 0; i < g->vertex_num; i++)
for (j = 0; j < g->vertex_num; j++)
{
g->Edges[i][j] = 0;
}
cout << "输入每条边对应的两个顶点的序号和权值" << endl;
for (k = 0; k < g->edge_num; k++)
{
cin >> i >> j >> w;
g->Edges[i][j] = w;
// g->Edges[j][i] = w;
}
return g;
}
void DFS( MGraph * g , int i )
{
Stack<int> s;
cout<<"已访问的节点:"<<g->Vertices[i]<<endl;
Visited[i]=1;
int f=0;
for( int j = 0 ; j < g->vertex_num ; j++)
{
cout<<i<<":"<<j<<endl;
if( g->Edges[i][j] == 1 && !Visited[j])
{
Visited[j]=1;
s.Push(i);
i=j;
j=0;
f=1;
}
if( j == g->vertex_num-1 && !s.IsEmpty() )
{
i=s.Top();
s.Pop();
j=0;
}
}
}
int main()
{
MGraph * g;
g = CreateMGraph();
for (int i = 0; i < g->vertex_num; i++)
{
for (int j = 0; j < g->vertex_num; j++)
{
cout << g->Edges[j][i] << " ";
}
cout << endl;
}
DFS(g,0);
return 0;
}
2.BFS(广度优先遍历)
BFS:访问某节点N,然后遍历其临接并且未被访问的节点,让后从这些节点出发依次遍历,直到所有节点都被访问。
a.邻接矩阵的BFS
void BFS( MGraph * g , int n )
{
Queue<int> q;
cout<<"已访问节点:"<<g->Vertices[n]<<endl;
for( int j = 0 ; j < g->vertex_num ; j++ )
{
if( g->Edges[n][j] == 1 && !Visited[j])
{
cout<<"已访问节点:"<<g->Vertices[j]<<endl;
q.Enqueue(j);
Visited[j]=1;
}
}
while(!q.IsEmpty())
{
n = q.FrontAndDequeue();
for( int j = 0 ; j < g->vertex_num ; j++ )
{
if( g->Edges[n][j] == 1 && !Visited[j])
{
cout<<"已访问节点:"<<g->Vertices[j]<<endl;
q.Enqueue(j);
Visited[j]=1;
}
}
}
}