图的遍历

来源:互联网 发布:什么是微观数据 编辑:程序博客网 时间:2024/05/22 02:38
A,图的存储结构:通常图有两种存储结构,邻接矩阵存储和邻接表存储。
(1)邻接矩阵:该存储结构用两个数组来表示图的信息,一个一维矩阵数组存储顶点信息,一个二维数组存储图中边的信息。一般如果一个图它的边数很多或者边很密集,这时邻接矩阵是一种比较好的存储结构。
a)设无向图G中有n个顶点,则其邻接矩阵是一个n阶方阵,定义为:
     图的遍历
下图为无向图的邻接矩阵:

图的遍历
b)设有向图G有n个节点,其邻接矩阵也为n阶方阵,定义为:

图的遍历
下图为有向网图的邻接矩阵:
图的遍历

(2)邻接表:该存储结构使用一个一维数组表示节点信息,然后每个节点的所有邻接点构成一个线性表。
a)下图是一个无向图且边不带权值的邻接表结构:
    
b)下图是一个带权有向图的邻接表结构:

图的遍历
B,图的遍历
(1)深度优先搜索:深度优先搜索类似于树的先序遍历,从图中某一个节点开始,先访问根节点,再从左到右依次访问孩子节点,直到图中所有节点都被访问了一次,遍历结束。
下图为用深度优先搜索时节点的访问顺序:
图的遍历

深度优先搜索算法实现:
#include "iostream"
using namespace std;
typedef char VertexType;//定义邻接矩阵节点的类型
#define MAXVEX 50//图中最大节点数
typedef struct //定义邻接矩阵的数据结构
{
VertexType vexs[MAXVEX];
int edges[MAXVEX][MAXVEX];
int vexNum, adgeNum;//分别表示图中节点个数和边的条数
}AGraph;
void createAGraph(AGraph *g)//创建图的邻接矩阵
{
int vNum, aNum;//分别代表要创建的图的节点数和边数
int start, end;//start->end表示节点start和end之间有一条边
cout<<"请输入图中节点的个数和边的条数:";
cin>>vNum>>aNum;
printf("\n请输入%d个节点的信息:", vNum);
//创建节点
for(int i = 0; i < vNum; ++i)
{
cin>>g->vexs[i];
}
cout<<"这里输出节点编号及其存储的节点信息"<<endl;
for(int k = 0; k < vNum; ++k)
cout<<k<<":"<<g->vexs[k]<<"";
cout<<endl;
//初始化边信息
for(int m = 0; m < vNum; ++m)
for(int n = 0; n < vNum; ++n)
g->edges[m][n] = 0;
//创建无向图的边信息
for(int j = 0; j < aNum; ++j)
{
cout<<"\n请输入第"<<j+1<<"条边的start和end节点:";
cin>>start>>end;
g->edges[start][end] = 1;
g->edges[end][start] = 1;
}
//初始化vexNum和adgeNum
g->vexNum = vNum;
g->adgeNum = aNum;
}
int main()
{
void DFS(AGraph, int, int[]);
AGraph g;
createAGraph(&g);
int visited[MAXVEX];
for(int i = 0; i < MAXVEX; ++i)
visited[i] = 0;
cout<<"\n深度优先搜索的访问顺序为:";
DFS(g, 0, visited);
cout<<endl;
return 0;
}
//深度优先搜索
//g为待遍历的图,i为图中遍历的第一个节点,visited表示访问标识
void DFS(AGraph g, int s, int visited[])
{
cout<<g.vexs[s]<<" ";
visited[s] = 1;
for(int i = 0; i < g.vexNum; ++i)
if((g.edges[s][i] == 1) && visited[i] == 0)
DFS(g, i, visited);
}
运行结果:
图的遍历

(2)广度优先搜索:这种遍历方式类似于树的层次遍历,从图中某一节点出发,越靠近该节点的层次越先访问到。
下图为广度优先搜索时节点的访问顺序:
图的遍历

广度优先搜索算法实现:
#include "iostream"
using namespace std;
typedef char VertexType;//定义邻接矩阵节点的类型
#define MAXVEX 50//图中最大节点数
typedef struct //定义邻接矩阵的数据结构
{
VertexType vexs[MAXVEX];
int edges[MAXVEX][MAXVEX];
int vexNum, adgeNum;//分别表示图中节点个数和边的条数
}AGraph;
void createAGraph(AGraph *g)//创建图的邻接矩阵
{
int vNum, aNum;//分别代表要创建的图的节点数和边数
int start, end;//start->end表示节点start和end之间有一条边
cout<<"请输入图中节点的个数和边的条数:";
cin>>vNum>>aNum;
printf("\n请输入%d个节点的信息:", vNum);
//创建节点
for(int i = 0; i < vNum; ++i)
{
cin>>g->vexs[i];
}
cout<<"这里输出节点编号及其存储的节点信息"<<endl;
for(int k = 0; k < vNum; ++k)
cout<<k<<":"<<g->vexs[k]<<"";
cout<<endl;
//初始化边信息
for(int m = 0; m < vNum; ++m)
for(int n = 0; n < vNum; ++n)
g->edges[m][n] = 0;
//创建无向图的边信息
for(int j = 0; j < aNum; ++j)
{
cout<<"\n请输入第"<<j+1<<"条边的start和end节点:";
cin>>start>>end;
g->edges[start][end] = 1;
g->edges[end][start] = 1;
}
//初始化vexNum和adgeNum
g->vexNum = vNum;
g->adgeNum = aNum;
}
int main()
{
void BFS(AGraph, int, int[]);
AGraph g;
createAGraph(&g);
int visited[MAXVEX];
for(int i = 0; i < MAXVEX; ++i)
visited[i] = 0;
cout<<"\n广度优先搜索的访问顺序为:";
BFS(g, 0, visited);
cout<<endl;
return 0;
}
//广度优先搜索
//g为待遍历的图,i为图中遍历的第一个节点,visited表示访问标识
void BFS(AGraph g, int s, int visited[])
{
int stack[MAXVEX];//定义一个用于存放中间节点编号的栈
int front, rear;//栈底和栈顶指针
front = rear = -1;
int current;//当前正在访问点的节点
stack[++rear] = s;
visited[rear] = 1;
while(front < rear)//栈空说明已经访问了图中所有节点一次
{
front = (front + 1) % MAXVEX;
current = stack[front];
cout<<g.vexs[current]<<" ";
for(int j = 0; j < g.vexNum; ++j)
if((g.edges[current][j] == 1) && (visited[j] ==0))
{
rear = (rear + 1) % MAXVEX;
stack[rear] = j;
visited[j] = 1;
}

}
}
运行结果:
图的遍历


0 0
原创粉丝点击