无向图的建立及深度优先遍历
一个图,有很多存储结构,例如邻接矩阵,邻接表,十字链表,邻接多重表等
下面写写一个无向图的邻接表存储,并实现其深度优先(DFS)遍历:
- 详细了解请参照严蔚敏写的《数据结构c语言版》163页(主要了解头结点和边结点)
话不多说直接上代码吧
代码块
// 实验四无向图的深度优先搜索.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
typedef struct ArcNode { //表(边)节点,存储边信息的结构体
int adjvex; //存储与该边相连的另一个节点的索引
struct ArcNode *nextarc; //存储与表头节点相连的其他边节点的指针
string info; //存储边的信息,例如权值
}ArcNode;
typedef struct VNode {//存储头节点信息的结构体
char date; //存储头节点包含的数据,例如头节点的名字
ArcNode * firstarc; //指向链表的指针
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct {
AdjList vertices; //存储头节点的数组
int vexnum, arcnum; //当前图的vexnum顶点数和arcnum弧数
int kind;//图的种类,
}ALGraph;
int LocateVex(ALGraph &G, char &v1) //查找节点V1在图G的存储节点数组中的索引位置
{
int i;
for (i = 0;i<G.vexnum;i++)
{
if (G.vertices[i].date == v1) //如果数组中有这个节点,返回该节点在数组中的索引
return i;
}
printf("未查找到%c节点!", v1);
return ERROR;
}
//以邻接表存储创建图
void CreateAL(ALGraph &G)
{
ArcNode *p, *q;
char v1, v2;
char v;
int i, j, k, n;
cout << "请输入图的顶点数和弧数:" << endl;
cin >> G.vexnum; //输入图的顶点数量
cin >> G.arcnum; //输入图的弧(边)的数量
cout << "请输入顶点:" << endl;
for (i = 0;i<G.vexnum;i++) //创建头结点
{
cin >> v; //输入顶点数据
G.vertices[i].date = v;//存入顶点数据
G.vertices[i].firstarc = NULL;//将指针域置空
}
for (k = 0;k<G.arcnum;k++) //创建边,并连接头结点
{
cout << "请输入弧尾和弧头:";
cin >> v1; //v1为弧尾
cin >> v2; //v2为弧头
i = LocateVex(G, v1);j = LocateVex(G, v2);//得到弧尾弧头在数组中的下标
if (i==ERROR||j==ERROR) {//当i,j返回错误时退出
exit(ERROR);
}
if (G.vertices[i].firstarc == NULL) //如果头节点指针域为空新建一个边节点,让头节点的指针指向该边节点
{
p = (ArcNode *)new ArcNode;
G.vertices[i].firstarc = p;
q = G.vertices[i].firstarc;
}
else //链表的插入
{
q = G.vertices[i].firstarc;//获取头结点的表头指针
for (n = 0;n<G.arcnum;n++, q = q->nextarc)//将q指针移动至链表的尾巴处
{
if (!q->nextarc)
break;
}
p = (ArcNode *)new ArcNode;
q->nextarc = p; //将该边(弧)加入到链表中
q = q->nextarc;
}
q->adjvex = j; //记录弧头的索引
q->nextarc = NULL;
}
cout << "图构建成功!" << endl;
}
void DFS(ALGraph &G,int* visited,int v) {//从第v个节点出发递归深度优先遍历图G
visited[v] = 1;
cout << G.vertices[v].date << " ";
ArcNode* m;
if (G.vertices[v].firstarc == NULL)//当第v个节点没有邻接点时返回
return;
//对第V个节点的所有邻接点进行DFS遍历
for (m = G.vertices[v].firstarc;m != NULL;m = m->nextarc) {
if (!visited[m->adjvex])
DFS(G, visited, m->adjvex);
}
}
//基于邻接表的深度优先算法
void DFStraverse(ALGraph &G, int v) {//从第v个顶点出发递归深度遍历图G
int* visited = (int*)calloc(G.vexnum , sizeof(int));//开一个大小为节点数,数据为0的辅助数组
if (visited == NULL)
exit(ERROR);
int n=0;//记录连通分量的个数
for (;v < G.vexnum;++v) {
if (!visited[v]) {
printf("第%d连通分量:", ++n);
DFS(G, visited, v);//对尚未访问的头节点调用DFS
cout << endl;
}
}
cout << endl;
}
int main()
{
ALGraph G;
CreateAL(G);
DFStraverse(G, 0);
return 0;
}