无向图的建立及深度优先遍历
2017-12-12 16:36
239 查看
无向图的建立及深度优先遍历
一个图,有很多存储结构,例如邻接矩阵,邻接表,十字链表,邻接多重表等下面写写一个无向图的邻接表存储,并实现其深度优先(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 DFSt 4000 raverse(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; }
实验运行结果截图:
相关文章推荐
- 图------有向网的建立、深度优先遍历,广度优先遍历
- Java图的建立以及深度广度优先遍历(邻接矩阵)
- 图的建立、广度优先遍历和深度优先遍历
- 二叉树的建立和深度优先遍历
- Java 图的建立及DFS深度优先遍历
- 图的建立、广度优先遍历和深度优先遍历
- leetcode 749. Contain Virus 消灭病毒建立墙 + 深度优先遍历DFS
- 二叉树基本操作的递归实现(二叉树建立,先序,中序,后序,深度的递归遍历。广度优先,高度优先的非递归遍历)
- 图的深度、广度优先遍历
- C#一颗简单多叉树的实现(原理、广度优先遍历、深度优先遍历)
- 二叉树的建立(非递归建立与定义建立)与基本操作(广度和深度遍历,求叶子树高)实现
- leetcode 392. Is Subsequence 子序列判断 深度优先遍历DFS + 一个很简单的循环
- (1.2.6.1)图的遍历--深度优先、广度优先
- 邻接矩阵c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)
- 深度优先遍历在编译器中的妙用
- leetcode 404. Sum of Left Leaves 所有左孩子叶节点之和计算 + 深度优先遍历DFS
- sdut 2136 数据结构实验之二叉树的建立与遍历(二叉树遍历,叶子数和深度)
- Java 递归形式深度优先遍历二叉树
- 图的遍历方法(深度优先和广度优先算法)
- 算法基础——DFS(深度优先遍历)