数据结构笔记--图的邻接表存储及非递归深度优先遍历
来源:互联网 发布:打字淘宝兼职是真的吗 编辑:程序博客网 时间:2024/05/16 00:28
最近在复习数据结构,看到图的时候就想尝试一下非递归的深度优先遍历,虽然写出来了,但是程序的可读性不高,所以在网上看了别人的实现,发现很多人只给了邻接矩阵存储的图的非递归遍历,所以作者自己实现了邻接表存储的图的创建和非递归遍历,水平有限,可读性健壮性尽量努力提高,图的邻接矩阵存储本文不涉及,仅仅介绍邻接表存储。
1、创建图的邻接表结构:
图的邻接表结构可以存储有向图和无向图而不用改任何东西,图的邻接表分为表头节点表和边表,表头节点主要为表头节点数组以及一个指向边表的指针。边表有n个边链表组成。
图的定义如下:
#define MAX_NODE 10typedef char DataType; //存储边信息的链表节点typedef struct ArcNode{ int m_index; //边表数据域保存顶点下标 struct ArcNode* m_next;}ArcNode;//存储定点信息的结构体定义typedef struct VertexNode{ DataType m_data; struct ArcNode* m_first;}VertexNode;//图的定义typedef struct Graphic{ VertexNode vertex[MAX_NODE]; int vexnum, arcnum; //图的顶点和边数量}AdjList;//找值data在数组vArray中的下标int Index(char data, VertexNode* vArray, int len){ for (int i = 0; i < len; ++i) { if (data == vArray[i].m_data) return i; } return -1;}//创建图的邻接表存储void Create(AdjList* grap){ cout << "请输入图的顶点数和边数: "; cin >> grap->vexnum >> grap->arcnum; if (grap->vexnum > MAX_NODE) { cout << "输入顶点过多!!!" << endl; return; } cout << "请输入顶点: "; for (int i = 0; i < grap->vexnum; ++i) { cin >> grap->vertex[i].m_data; grap->vertex[i].m_first = NULL; } cout << "请输入边: " << endl; for (int i = 0; i < grap->arcnum; ++i) { char a1, a2; cin >> a1 >> a2; int index1, index2; index1 = Index(a1, grap->vertex, grap->vexnum); index2 = Index(a2, grap->vertex, grap->vexnum); if (index1 == -1 || index2 == -2) { cout << "输入参数有误!!!" << endl; --i; continue; } ArcNode *p = new ArcNode; p->m_index = index2; p->m_next = grap->vertex[index1].m_first; grap->vertex[index1].m_first = p; }}
2、深度优先搜索的非递归实现:
要实现非递归的深度优先搜索,要用到到栈来存储,用一个数组visited(初始所有元素为false,代表未访问)来做访问的标记。基本思想是:从给定的搜索的第一个顶点index开始,将其压入堆栈,并标记visited[]为true表示已访问;之后循环进行如下操作,只要栈不为空,取出最上方元素,将其打印,然后去遍历所有的邻接顶点,只要还未访问(visited相应值为false),就将其压入栈,并标记为已访问。当栈中元素为0时,算法结束时,而所有访问过的点,均被标记过,并被压入栈中过,只要图是连通的,那么就做到所有点都被输出或记录。
注意:刚才有提过,以上针对于连通的图,而对于图中存在不同的连通分量的情况,可以在一次while循环之后,检查visited判断是否所有元素都被访问过,若存在未被访问的点,则在选取一个点,重复以上操作即可。
//非递归深度优先遍历连通子图void Depth(AdjList* grap, int index, bool* visited){ stack<int> stackIndex; stackIndex.push(index); while (!stackIndex.empty()) { int v0 = stackIndex.top(); stackIndex.pop(); if (!visited[v0]) { cout << grap->vertex[v0].m_data << " "; visited[v0] = true; } ArcNode* p = grap->vertex[v0].m_first; while (p) { if (!visited[p->m_index]) { stackIndex.push(p->m_index); } p = p->m_next; } }}//非递归深度优先遍历图,封装上述函数void DFS1(AdjList* grap, int index, bool* visited){ for (int i = 0; i < grap->vexnum; ++i) { visited[i] = false; } for (int i = 0; i < grap->vexnum; ++i) { if (visited[i] == false) { Depth(grap, i, visited); } }}
参考:数据结构-C语言描述 耿国华著
0 0
- 数据结构笔记--图的邻接表存储及非递归深度优先遍历
- 邻接表存储图的深度优先、广度优先遍历非递归算法
- 图的邻接表存储及深度优先遍历程序
- 【数据结构】邻接表表示法的图的深度广度优先遍历递归和非递归遍历
- 图的深度优先搜索遍历(邻接表&邻接矩阵,递归&非递归)(C++)
- 图的深度优先遍历(递归、非递归;邻接表,邻接矩阵)
- 图的深度优先遍历,基于邻接链表的非递归实现
- 图的邻接表存储下的深度优先遍历
- 图的邻接表存储与深度优先遍历算法
- 图的深度优先遍历(邻接表存储)
- 利用邻接表存储图,实现其递归与非递归的深度遍历和广度遍历
- 【数据结构】邻接矩阵表示法的图的深度广度优先遍历递归和非递归遍历
- 【数据结构】邻接矩阵表示法的图的深度广度优先遍历递归和非递归遍历
- 图邻接表存储 深度优先和广度优先遍历
- 有向图的邻接表存储,递归和非递归的深度、广度遍历(codeblocks+gcc)
- 图的邻接表存储 深度优先遍历 广度优先遍历 C语言实现
- 图的邻接表存储 深度优先遍历 广度优先遍历 C语言实现
- 数据结构 — 图之邻接表存储创建和深度优先遍历
- Oracle(入门一)
- GFFMPEG系统结构简介
- 元素hidden与opacity=0的区别
- LeetCode 88. Merge Sorted Array
- ubuntu 安装vagrant过程
- 数据结构笔记--图的邻接表存储及非递归深度优先遍历
- How to get file path in onActivityResult in Android 4.4
- 模态弹出的页面push或pop到其他页面
- 基于R语言的用户征信行为分类预测模型搭建总结
- NAT和代理服务器解析
- 最近遇到的一些问题以及解决方案
- python gzip模块
- hdu3251 最小割
- **PDO** php_mysql插入查询排序