这是用无向图的广度优先搜索代码,如果是有向图需要稍微修改,否则产生死循环。
邻接矩阵表示的无向图的广度优先搜索:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define N 6
#define INFINITE 0x7fffffff
#define WHITE 1
#define GRAY 2
#define BLACK 3
//图结构
struct Graph
{
int map[N+1][N+1];
int d[N+1];//与源点之间的距离
int p[N+1];//指向遍历结果的父结点
int color[N+1];//颜色
Graph()
{
memset(map, 0, sizeof(map));
}
};
std::queue<int>MyQueue;
bool InsertEdge(Graph *G, int row, int col,int val);
void Print(Graph *G);
bool Init(Graph *g);
bool BreadthFirstSearch(Graph *g,int vertex);
//插入边
bool InsertEdge(Graph *G, int row, int col,int val)
{
G->map[row][col] = val;
return true;
}
//输出邻接矩阵表示的图
void Print(Graph *G)
{
int i, j;
std::cout<<"\t";
for(i = 1; i <= N; i++)
{
std::cout<<i<<"\t";
}
std::cout<<std::endl<<std::endl;
//遍历每个顶点
for(i = 1; i <= N; i++)
{
cout<<i<<"\t";
//输出以i为起点的边的终点
for(j = 1; j <= N; j++)
{
if(G->map[i][j] == 1)
{
std::cout<<1<<"\t";
}
else
{
std::cout<<0<<"\t";
}
}
std::cout<<endl;
}
std::cout<<endl;
}
/*初始化临接表表示的图,为了简化应该是无向图。
0 1 0 1 0 0
0 0 0 0 1 0
0 0 0 0 1 1
0 1 0 0 0 0
0 0 0 1 0 0
0 0 0 0 0 1
*/
bool Init(Graph *g)
{
InsertEdge(g,1,2,1);
InsertEdge(g,2,1,1);
InsertEdge(g,1,4,1);
InsertEdge(g,4,1,1);
InsertEdge(g,2,5,1);
InsertEdge(g,5,2,1);
InsertEdge(g,3,5,1);
InsertEdge(g,5,3,1);
InsertEdge(g,3,6,1);
InsertEdge(g,6,3,1);
InsertEdge(g,4,2,1);
InsertEdge(g,2,4,1);
InsertEdge(g,5,4,1);
InsertEdge(g,4,5,1);
InsertEdge(g,6,6,1);
return true;
}
/*
宽度优先搜索,vertex为初试的节点
这种方法适合于无向图,如果是有向图会产生死循环
*/
bool BreadthFirstSearch(Graph *g,int vertex)
{
//对所有结点进行初始化
for(int i = 1; i <= N; i++)
{
g->color[i] = WHITE;
g->d[i] = INFINITE;
g->p[i] = -1;
}
g->color[vertex] = GRAY;
g->d[vertex] = 0;
g->p[vertex] = -1;
while(!MyQueue.empty())
{
MyQueue.pop();
}
MyQueue.push(vertex);
while(!MyQueue.empty())
{
int node = MyQueue.front();
MyQueue.pop();
std::cout<<node<<"\t";
for(int i=1;i<=N;i++)
{
if(g->map[node][i] == 0)
{
continue;
}
if(g->color[i] == GRAY)
{
continue;
}
g->color[i] = GRAY;
g->d[i] = g->d[node] + 1;
g->p[i] = node;
MyQueue.push(i);
}
g->color[node] == BLACK;
}
return true;
}
int main()
{
//构造一个空的图
Graph *g = new Graph;
Init(g);
//Print(g);
BreadthFirstSearch(g,6);
getchar();
return 0;
}
邻接表表示的无向图的广度优先搜索:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define N 6
#define INFINITE 0x7fffffff
#define WHITE 1
#define GRAY 2
#define BLACK 3
//顶点结点结构
struct Vertex
{
Vertex * next;/*指向下一个顶点*/
int id;/*节点的标志*/
int color;//颜色
Vertex *p;//指向遍历结果的父结点
int d;//与源点之间的距离
Vertex():next(NULL),id(0),color(WHITE),p(NULL),d(INFINITE){}
};
//图结构
struct Graph
{
Vertex *Adj[N+1];//N个顶点
Graph()
{
for(int i = 1; i <= N; i++)
Adj[i] = new Vertex;
}
~Graph()
{
for(int i = 1; i <= N; i++)
delete Adj[i];
}
};
std::queue<int>Q;/*队列,保存搜索过程的中间数据*/
void Print(Graph *g);
bool Init(Graph *g);
bool InsertEdge(Graph *g , int start,int end);
void PaintColor(Graph *g,int vertex,int color);
//插入边
bool InsertEdge(Graph *g , int start,int end)
{
Vertex* v = new Vertex();
v->id = end;
if(g->Adj[start]->next == NULL)
{/*如果不存在临界表的头结点列表中,则插入*/
Vertex* s = new Vertex();
s->id = start;
g->Adj[start] = s;
}
Vertex* tmp = g->Adj[start];
while(tmp->next)
{
tmp = tmp->next;
}
tmp->next =v;
return true;
}
/*初始化邻接表表示的图,无向图。
1->2->4
2->1->4->5
3->6->5
4->1->2->5
5->2->3->4
6->6->3
*/
bool Init(Graph *g)
{
InsertEdge(g,1,2);
InsertEdge(g,2,1);
InsertEdge(g,1,4);
InsertEdge(g,4,1);
InsertEdge(g,2,5);
InsertEdge(g,5,2);
InsertEdge(g,3,5);
InsertEdge(g,5,3);
InsertEdge(g,3,6);
InsertEdge(g,6,3);
InsertEdge(g,4,2);
InsertEdge(g,2,4);
InsertEdge(g,5,4);
InsertEdge(g,4,5);
InsertEdge(g,6,6);
return true;
}
/*
宽度优先搜索,vertex为初试的节点
这种方法适合于无向图,如果是有向图会产生死循环
*/
bool BreadFirstSearch(Graph *g,int vertex)
{
//对所有结点进行初始化
for(int i = 1; i <= N; i++)
{
g->Adj[i]->color = WHITE;
g->Adj[i]->d = INFINITE;
g->Adj[i]->p = NULL;
}
PaintColor(g,vertex,GRAY);
g->Adj[vertex]->d = 0;
g->Adj[vertex]->p = NULL;
while(!Q.empty())
{
Q.pop();
}
Q.push(vertex);
while(!Q.empty())
{ /*应该存储节点的ID,不应该是数据结构,可以节省存储空间*/
int node = Q.front();
Vertex *v = g->Adj[node]; //Q.front();
Q.pop();
std::cout<<v->id<<"\t";
while(v)
{
if(v->color == WHITE)
{
PaintColor(g,v->id,GRAY);
g->Adj[v->id]->d = g->Adj[node]->d +1;
Q.push(v->id);
}
v = v->next;
}
PaintColor(g,node,BLACK);
}
return true;
}
/*
对临界表的节点染色
*/
void PaintColor(Graph *g,int vertex,int color)
{
g->Adj[vertex]->color = color;
for(int i=1;i<=N;i++)
{
Vertex *v = g->Adj[i];
v = v->next;
while(v)
{
if(v->id == vertex)
{
v->color = color;
}
v = v->next;
}
}
}
int main()
{
//构造一个空的图
Graph *g = new Graph;
Init(g);
BreadFirstSearch(g,1);
getchar();
return 0;
}