实验内容
功能 |
---|
图的邻接表定义及创建 |
无向图上实现深度优先算法 |
无向图上实现广度优先遍历算法 |
有向无环图上实现拓扑排序算法 |
数据结构定义
算法思想及算法设计
(1) 图的邻接表表示法创建(以无向图为例)
图的邻接表表示法类似于树的孩子链表表示法。对于图G中的每个顶点vi,该方法把所有邻接于vi的顶点vj链成一个带头节点的单链表,这个单链表就称为顶点vj的邻接表。单链表中的每个结点至少包含两个域,一个为邻接点域,它指示与顶点vi邻接的顶点在图中的位序;另一个为链域,它指示与顶点vi邻接的下一个节点。在每个链表上需附设一个表头结点,在表头结点中,除了设有头指针域(firstedge)指向链表中的第一个结点之外,还设有存储顶点vi的数据域(vertex)或其他有关信息的数据域。
在创建的过程,首先要输入该图所拥有的顶点数和边数,之后依次输入依附于一条边的顶点,因为为无向图,所以只输入一次即可,找到两个顶点在顶点数组中的下标,之后创建新节点,利用头插法将其插入到分别以两个顶点为头的链表上。
(2) 深度优先遍历
用深度优先搜索策略遍历一个图类似于树的前序遍历,对于一个图G=(V,E),首先将图中的每一个顶点都标记为未访问,然后选取一个源点v,将其标为已访问,再递归地用深度优先搜索方法,依次搜索该点的所有邻接点w。若w未曾访问,则以w为源点继续进行深度优先遍历,如果从v出发的所有路的顶点都已被访问过,则从v的搜索过程结束。此时如果图中还有未被访问的顶点(该图有多个连通分量或强连通分量),则再任选一个未被访问过的顶点,从这个顶点开始新的搜索,直到V中所有顶点都已被访问过为止。首先,先将代表是否访问过该顶点的标志数组visited进行初始化,然后随便选取一个顶点作为第一个访问的顶点,调用DFS_UDG函数,并在visited数组进行标记,之后找到它的下一个未曾访问过的邻接点,进行递归调用DFS_UDG函数。
(3) 广度优先遍历
广度优先搜索策略遍历一个图类似于树的层次遍历,对于一个图G=(V,E),从图中的某个源点v出发,在访问了顶点v之后,接着就尽可能横向搜索v的所有邻接点。在依次访问v的各个未被访问过的邻接点w1、w2 … wk之后,分别从这些邻接点出发依次访问与w1、w2 …
wk邻接的所有未曾访问过的顶点。依此类推,直至图中所有和源点v有路径相通的顶点都已访问过为止,此时从v开始的搜索过程结束。若G是连通图,则遍历完成;否则,在G中另选一个尚未访问过的顶点作为新的源点继续上述搜索过程,直至G中所有顶点均被访问完为止。首先,先将代表是否访问过该顶点的标志数组visited进行初始化,然后随便选取一个顶点作为第一个访问的顶点,调用BFS_UDG函数,并在visited数组中进行标记。设置一个队列,用来存储已经访问过的顶点。输出第一个顶点值,并将其进队。找到队头元素,顺势将其出队,并找到它的邻接点,输出未曾访问过的邻接点,并将其进队,进行该循环,直到队空时停止循环。
(4) 拓扑排序
首先设置一个存放顶点入度的数组InDegree,通过调用函数FindInDegree将其初始化。另外设置一个栈,用来暂存所有入度为零的顶点。当栈不为空时,进行以下循环:取栈顶并输出,顺势将其出栈,同时count++用于对输出结点进行计数。之后探索其邻接点,并将其入度减一,然后判断此时该顶点入度是否为零,若为一,则进栈。最后判断count与顶点总数的关系,判断该图是否为有向有环图。
实验代码
头文件及数据定义
#include<iostream>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;
#define MAX_VNODE_NUM 100
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
typedef int Status;
typedef int VRType; //顶点关系类型
typedef char VertexType;
typedef char InfoType;
enum GraphKind{
UDG,UDN,DG,DN};
typedef struct ArcNode //边结点
{
int adj; //该边所指向顶点的位置
int weight=0;
struct ArcNode* nextarc; //指向下一条边的指针
InfoType *info;
}ArcNode;
typedef struct VNode
{
VertexType data; //顶点信息
ArcNode *firstarc; //指向第一条依附该顶点的的边的指针
}VNode,Adjlist[MAX_VNODE_NUM];
typedef struct //邻接表
{
Adjlist vertices;
int vexnum,arcnum;
GraphKind kind;
}ALGraph;
int visited[MAX_VNODE_NUM];
int indegree[MAX_VNODE_NUM];
图的邻接表表示法的创建
Status CreateUDG(ALGraph &G)
{
int i,j,k;
VertexType va,vb;
cout << "请在下列输入无向图的顶点数,边数"<<endl;
cout << "请输入顶点数: "