图的生成、图的遍历

合集下载

图的遍历算法

图的遍历算法

1图的遍历问题在实践中常常遇到这样的问题:给定n个点,从任一点出发对所有的点访问一次并且只访问一次。

如果用图中的顶点表示这些点,图中的边表示可能的连接,那么这个问题就可以表示成图的遍历问题,即从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。

图的遍历操作和树的遍历操作功能相似,是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础上。

由于图结构本身的复杂性,所以图的遍历操作也比较复杂,主要表现在以下几个方面:(1) 在图结构中,没有一个确定的首结点,图中任意一个顶点都可以作为第一个被访问的结点。

(2) 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上的所有顶点,因此,还需要考虑如何选取下一个出发点以访问图中其余的连通分量。

(3) 在图结构中,如果有回路存在,那么一个顶点被访问后,有可能沿回路又回到该顶点。

⑷在图结构中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,存在如何选取下一个要访问的顶点的问题。

基于以上分析,图的遍历方法目前有深度优先搜索(DFS)和广度优先搜索(BFS)两种算法。

下面将介绍两种算法的实现思路,分析算法效率并编程实现。

1.1深度优先搜索算法深度优先搜索算法是树的先根遍历的推广,它的实现思想是:从图G的某个顶点V o出发,访问V o,然后选择一个与V o相邻且没被访问过的顶点V i访问,再从V i出发选择一个与V i相邻且未被访问的顶点V j进行访问,依次继续。

如果当前被访问过的顶点的所有邻接顶点都已被访问,贝U退回已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样的方法向前遍历,直到图中所有顶点都被访问。

其递归算法如下:Boolean visited[MAX_VERTEX_NUM]; // 访问标志数组Status (*VisitFunc)(int v); //VisitFunc是访问函数,对图的每个顶点调用该函数void DFSTraverse (Graph G Status(*Visit)(i nt v)){VisitF unc = Visit;for(v=0; vvG.vex num; ++v)visited[v] = FALSE; //访问标志数组初始化for(v=0; v<G .vex num; ++v)if(!visited[v])DFS(G v); //对尚未访问的顶点调用DFS}void DFS(Graph G int v){ //从第v个顶点出发递归地深度优先遍历图Gvisited[v]=TRUE; VisitFunc(v); // 访问第v 个顶点for(w=FirstAdjVex(G ,v); w>=0;w=NextAdjVex(G ,v,w))//FirstAdjVex返回v的第一个邻接顶点,若顶点在G中没有邻接顶点,则返回空(0)。

第15讲图的遍历

第15讲图的遍历

V6
V8
V8
V7
V5 深度优先生成树
V8 V1
V2
V3
V4 V5 V6 V7
V8 广度优先生成树
27
例A
B
CD E
F
GH
I
K
J
L
M
A
D
G
LCF
KI E
H M
JB
深度优先生成森林
28
二、图的连通性问题
▪1、生成树和生成森林
▪ 说明
G
▪ 一个图可以有许多棵不同的生成树
KI
▪ 所有生成树具有以下共同特点:
g.NextAdjVex(v, w))
{
if (g.GetTag(w) == UNVISITED)
{
g.SetTag(w, VISITED);
g.GetElem(w, e);
Visit(e);
q.InQueue(w);
}
}}}
24
一、图的遍历 两种遍历的比较
V0
V1 V4
V0
V1 V4
V3
V2 V5
16
一、图的遍历
广度优先遍历序列?入队序列?出队序列?
V1
V2
V3
V1
V4
V5 V6
V7
V8
遍历序列: V1
17
一、图的遍历
广度优先遍历序列?入队序列?出队序列?
V1
V2
V3
V2 V3
V4
V5 V6
V7
V8
遍历序列: V1 V2 V3
18
一、图的遍历
广度优先遍历序列?入队序列?出队序列?
V1
V2

图的遍历 实验报告

图的遍历  实验报告

图的遍历实验报告一、引言图是一种非线性的数据结构,由一组节点(顶点)和节点之间的连线(边)组成。

图的遍历是指按照某种规则依次访问图中的每个节点,以便获取或处理节点中的信息。

图的遍历在计算机科学领域中有着广泛的应用,例如在社交网络中寻找关系紧密的人员,或者在地图中搜索最短路径等。

本实验旨在通过实际操作,掌握图的遍历算法。

在本实验中,我们将实现两种常见的图的遍历算法:深度优先搜索(DFS)和广度优先搜索(BFS),并比较它们的差异和适用场景。

二、实验目的1. 理解和掌握图的遍历算法的原理与实现;2. 比较深度优先搜索和广度优先搜索的差异;3. 掌握图的遍历算法在实际问题中的应用。

三、实验步骤实验材料1. 计算机;2. 编程环境(例如Python、Java等);3. 支持图操作的相关库(如NetworkX)。

实验流程1. 初始化图数据结构,创建节点和边;2. 实现深度优先搜索算法;3. 实现广度优先搜索算法;4. 比较两种算法的时间复杂度和空间复杂度;5. 比较两种算法的遍历顺序和适用场景;6. 在一个具体问题中应用图的遍历算法。

四、实验结果1. 深度优先搜索(DFS)深度优先搜索是一种通过探索图的深度来遍历节点的算法。

具体实现时,我们可以使用递归或栈来实现深度优先搜索。

算法的基本思想是从起始节点开始,选择一个相邻节点进行探索,直到达到最深的节点为止,然后返回上一个节点,再继续探索其他未被访问的节点。

2. 广度优先搜索(BFS)广度优先搜索是一种逐层遍历节点的算法。

具体实现时,我们可以使用队列来实现广度优先搜索。

算法的基本思想是从起始节点开始,依次遍历当前节点的所有相邻节点,并将这些相邻节点加入队列中,然后再依次遍历队列中的节点,直到队列为空。

3. 时间复杂度和空间复杂度深度优先搜索和广度优先搜索的时间复杂度和空间复杂度如下表所示:算法时间复杂度空间复杂度深度优先搜索O(V+E) O(V)广度优先搜索O(V+E) O(V)其中,V表示节点的数量,E表示边的数量。

数据结构与算法 图的遍历与连通性

数据结构与算法 图的遍历与连通性

数据结构与算法图的遍历与连通性数据结构与算法:图的遍历与连通性在计算机科学中,数据结构和算法是解决各种问题的基石。

其中,图作为一种重要的数据结构,其遍历和连通性的研究具有至关重要的意义。

让我们先来理解一下什么是图。

简单来说,图是由顶点(也称为节点)和边组成的结构。

顶点代表了事物或者对象,而边则表示顶点之间的关系。

例如,在一个社交网络中,人可以被视为顶点,而人与人之间的好友关系就是边。

图的遍历是指按照一定的规则访问图中的所有顶点。

常见的图遍历算法有深度优先遍历和广度优先遍历。

深度优先遍历就像是一个勇敢的探险家,一头扎进未知的领域,勇往直前,直到走投无路,然后回溯。

它的基本思想是先访问一个顶点,然后沿着一条未访问过的边递归地访问下一个顶点,直到没有可访问的边,再回溯到之前的顶点,继续探索其他未访问的边。

想象一下你在一个迷宫中,选择一条路一直走到底,直到遇到死胡同或者已经没有新的路可走,然后再返回之前的岔路口,选择另一条路继续前进。

广度优先遍历则像是一个谨慎的旅行者,逐层探索。

它先访问起始顶点,然后依次访问其所有相邻的顶点,再依次访问这些相邻顶点的相邻顶点,以此类推。

这就好比你在散播消息,先告诉离你最近的人,然后他们再告诉他们附近的人,一层一层地传播出去。

那么,为什么我们要进行图的遍历呢?这是因为通过遍历图,我们可以获取图的各种信息,比如顶点之间的关系、图的结构特点等。

在实际应用中,图的遍历有着广泛的用途。

例如,在搜索引擎中,通过遍历网页之间的链接关系来抓取和索引网页;在社交网络分析中,遍历用户之间的关系来发现社区结构等。

接下来,我们谈谈图的连通性。

连通性是指图中顶点之间是否存在路径相连。

如果从图中的任意一个顶点都可以到达其他任意一个顶点,那么这个图就是连通图;否则,就是非连通图。

判断图的连通性是一个重要的问题。

一种常见的方法是从某个顶点开始进行遍历,如果能够访问到所有的顶点,那么图就是连通的;否则,图是非连通的。

图的遍历及生成树

图的遍历及生成树

• •邻接表的DFS算法
void DFS(ALGraph G, int v) { ArcNode *p;
visited[v] = 1; /*置已访问标记*/ printf("%d ", v); /*输出被访问顶点的编号*/ p = G.vertices[v].firstarc; /*p指向顶点v的第一个邻接点*/ while (p!=NULL) {
•v11
•v1,
•v2
•v3
•v2,
•v4,
•v5
•v8,
•v4
•v6
•v7
•v5,
•v3,
•v8
•v6,
•v7

•图的DFS算法一般描述
•int visited[MAXVEX]; //访问标志数组
•void DFSTraverse(Graph G)
•{ //对图G作深度优先遍历
• for( v=0; v<G.vexnum; ++v ) visited[v]=FALSE;
•} // DFS1
•G.arcs[v][j] =1
•有邻接点
•visited [n]=0
•未访问过

分析:
在遍历图时,对图中每个顶点至多调用一次DFS函数 ,因为一旦某个顶点被标志成已被访问,就不再从它出发 进行搜索。
因此,遍历图的过程实质上是对每个顶点查找其邻接 点的过程。其耗费的时间则取决于所采用的存储结构。 如果用邻接矩阵来表示图,遍历图中每一个顶点都要从 头扫描该顶点所在行,因此遍历全部顶点所需的时间为 O(n2)。 如果用邻接表来表示图,虽然有 2e 个表结点,但只需扫 描 e 个结点即可完成遍历,加上访问 n个头结点的时间, 因此遍历图的时间复杂度为O(n+e)。

图的遍历的实验报告

图的遍历的实验报告

图的遍历的实验报告图的遍历的实验报告一、引言图是一种常见的数据结构,它由一组节点和连接这些节点的边组成。

图的遍历是指从图中的某个节点出发,按照一定的规则依次访问图中的所有节点。

图的遍历在许多实际问题中都有广泛的应用,例如社交网络分析、路线规划等。

本实验旨在通过实际操作,深入理解图的遍历算法的原理和应用。

二、实验目的1. 掌握图的遍历算法的基本原理;2. 实现图的深度优先搜索(DFS)和广度优先搜索(BFS)算法;3. 比较并分析DFS和BFS算法的时间复杂度和空间复杂度。

三、实验过程1. 实验环境本实验使用Python编程语言进行实验,使用了networkx库来构建和操作图。

2. 实验步骤(1)首先,我们使用networkx库创建一个包含10个节点的无向图,并添加边以建立节点之间的连接关系。

(2)接下来,我们实现深度优先搜索算法。

深度优先搜索从起始节点开始,依次访问与当前节点相邻的未访问过的节点,直到遍历完所有节点或无法继续访问为止。

(3)然后,我们实现广度优先搜索算法。

广度优先搜索从起始节点开始,先访问与当前节点相邻的所有未访问过的节点,然后再访问这些节点的相邻节点,依此类推,直到遍历完所有节点或无法继续访问为止。

(4)最后,我们比较并分析DFS和BFS算法的时间复杂度和空间复杂度。

四、实验结果经过实验,我们得到了如下结果:(1)DFS算法的时间复杂度为O(V+E),空间复杂度为O(V)。

(2)BFS算法的时间复杂度为O(V+E),空间复杂度为O(V)。

其中,V表示图中的节点数,E表示图中的边数。

五、实验分析通过对DFS和BFS算法的实验结果进行分析,我们可以得出以下结论:(1)DFS算法和BFS算法的时间复杂度都是线性的,与图中的节点数和边数呈正比关系。

(2)DFS算法和BFS算法的空间复杂度也都是线性的,与图中的节点数呈正比关系。

但是,DFS算法的空间复杂度比BFS算法小,因为DFS算法只需要保存当前路径上的节点,而BFS算法需要保存所有已访问过的节点。

数据结构 图 练习题

数据结构 图 练习题

数据结构图练习题数据结构图练习题在计算机科学领域中,数据结构是一种用来组织和存储数据的方式。

而图是一种常见的数据结构,它由一组节点和连接这些节点的边组成。

图可以用来表示各种各样的关系,比如社交网络中的用户关系、城市之间的道路网络等等。

在本文中,我们将探讨一些与图相关的练习题,帮助读者更好地理解和应用图的概念。

1. 最短路径问题最短路径问题是图论中的经典问题之一。

给定一个带权重的有向图,我们需要找到从一个起始节点到目标节点的最短路径。

这里的权重可以表示为距离、时间或者其他度量。

解决这个问题的算法有很多,其中最著名的是Dijkstra算法和Bellman-Ford算法。

读者可以尝试使用这些算法来解决一些具体的实例,比如计算两个城市之间的最短路径。

2. 拓扑排序拓扑排序是对有向无环图(Directed Acyclic Graph,简称DAG)进行排序的一种算法。

在一个DAG中,节点之间存在一种偏序关系,即某些节点必须在其他节点之前进行处理。

拓扑排序可以帮助我们确定这种偏序关系,从而找到一种合理的处理顺序。

比如,在编译器中,拓扑排序可以用来确定源代码中各个函数的调用顺序。

读者可以尝试编写一个拓扑排序算法,并应用到一些具体的场景中。

3. 最小生成树最小生成树是一个无向连通图中一棵权值最小的生成树。

在一个连通图中,最小生成树可以帮助我们找到一种最优的连接方式,以满足一些约束条件。

最常用的算法是Prim算法和Kruskal算法。

读者可以尝试使用这些算法来解决一些具体的实例,比如在一个城市之间建设光纤网络,以最小的成本实现全覆盖。

4. 图的遍历图的遍历是指按照某种方式访问图中的所有节点。

常见的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)。

DFS通过递归地访问每个节点的邻居节点,直到所有节点都被访问完。

BFS则通过队列来实现,先访问起始节点的邻居节点,然后依次访问它们的邻居节点,直到所有节点都被访问完。

计算机中图的名词解释

计算机中图的名词解释

计算机中图的名词解释在计算机领域中,图(Graph)是一种常见的数据结构,用于描述对象之间的关系和相互作用。

图的概念最早由数学家欧拉提出,并且在计算机科学中得到广泛运用。

本文将从图的基本概念和操作开始,逐步介绍计算机中图的相关术语和应用。

1. 图的基本概念图由节点(Node)和边(Edge)组成。

节点表示对象或实体,边表示节点之间的连接关系。

图可以分为有向图(Directed Graph)和无向图(Undirected Graph)。

在有向图中,边具有方向性,表示从一个节点流向另一个节点;而在无向图中,边没有方向性,表示两个节点之间的相互关系。

2. 图的存储方式为了在计算机中表示和处理图,常见的存储方式有邻接矩阵(Adjacency Matrix)和邻接表(Adjacency List)。

邻接矩阵是一个二维数组,其中行和列表示节点,矩阵的值表示节点之间是否有边相连。

邻接表则使用链表的形式来表示节点之间的连接关系,每个节点对应一个链表,链表中存储了与该节点相连的其他节点。

3. 图的遍历图的遍历是指沿着图中的路径,依次访问所有节点的过程。

常见的图遍历算法有深度优先搜索(Depth-First Search)和广度优先搜索(Breadth-First Search)。

深度优先搜索先选择一个起始节点,沿着路径一直深入直到无法继续,然后回溯到其他未访问的节点,继续深入;而广度优先搜索则是从起始节点开始,并逐层扩展,逐层访问。

4. 最短路径算法最短路径算法用于计算两个节点之间的最短路径,即路径上边的权值之和最小。

其中,最常用的最短路径算法是狄克斯特拉算法(Dijkstra Algorithm)。

该算法通过逐步更新节点到其他节点的距离,找到起始节点到目标节点的最短路径。

5. 拓扑排序拓扑排序(Topological Sorting)是一种对有向无环图进行排序的算法。

在有向图中,如果节点 A 的边指向节点 B,那么 B 必须在 A 之后才能出现在排序结果中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构B实验报告一、实验内容图的生成、图的遍历二、实验目的掌握图的基本存储结构掌握图的相关算法掌握图的两种遍历方法三、功能本实验要求实现以下功能:1.以邻接矩阵或者邻接表作为存储结构建立一个无向图。

2.深度优先搜索该无向图,输出遍历序列。

3.广度优先搜索该无向图,输出遍历序列。

四、主要代码#include<iostream>#include<fstream>using namespace std;enum Status{UNVISITED,VISITED,SUCCESS,OVER_FLOW, RANGE_ERROR, NOT_PRESENT, ENTRY_FOUND, UNDER_FLOW};const int DEFAULT_SIZE = 30;const int DEFAULT_INFAULTY =99999;const int MaxSize = 50;template<class ElemType>struct Node{ElemType data;Node<ElemType>*next;Node();//普通构造函数Node(ElemType e, Node<ElemType>*link = NULL);//带形参的构造函数};template<class ElemType>Node<ElemType>::Node(){next = NULL;}template<class ElemType>Node<ElemType>::Node(ElemType e, Node<ElemType>*link){data = e;next = link;}template<class ElemType>class LinkQueue{protected:Node<ElemType> *front, *rear; // 队头队尾指针public:LinkQueue();virtual ~LinkQueue();int GetLength() const;bool IsEmpty() const;void Clear();Status DelQueue(ElemType &e);Status GetHead(ElemType &e) const;Status EnQueue(const ElemType e);};template<class ElemType>LinkQueue<ElemType>::LinkQueue(){rear = front = new Node<ElemType>;}template<class ElemType>LinkQueue<ElemType>::~LinkQueue(){Clear();delete front;}template<class ElemType>int LinkQueue<ElemType>::GetLength() const{int count = 0;Node<ElemType> *p;for (p = front->next; p != NULL; p = p->next)count++;return count;}template<class ElemType>bool LinkQueue<ElemType>::IsEmpty() const{return rear == front;}template<class ElemType>void LinkQueue<ElemType>::Clear(){Node<ElemType> *p = front->next;while (p != NULL){front->next = p->next;delete p;p = front->next;}rear = front;}template<class ElemType>Status LinkQueue<ElemType>::EnQueue(const ElemType e) {Node<ElemType> *p;p = new Node<ElemType>(e);if (p){rear->next = p;rear = rear->next;return SUCCESS;}else return OVER_FLOW;}template<class ElemType>Status LinkQueue<ElemType>::GetHead(ElemType &e) const{if (!IsEmpty()){e = front->next->data;return SUCCESS;}else return UNDER_FLOW;}template<class ElemType>Status LinkQueue<ElemType>::DelQueue(ElemType &e){if (!IsEmpty()){Node<ElemType> *p = front->next;e = p->data;front->next = p->next;if (rear == p)rear = front;//队列中只有一个元素delete p;return SUCCESS;}else return UNDER_FLOW;}//定义有向网邻接表中弧结点的类模板template<class WeightType>struct AdjListNetworkArc{int adjVex;//弧头顶点序号WeightType weight;//边的权值AdjListNetworkArc<WeightType>*nextarc;//下一条边结点的指针AdjListNetworkArc();AdjListNetworkArc(int v, WeightType w, AdjListNetworkArc<WeightType>*next = NULL); };template<class WeightType>AdjListNetworkArc<WeightType>::AdjListNetworkArc(){adjVex = -1;}template<class WeightType>AdjListNetworkArc<WeightType>::AdjListNetworkArc(int v, WeightType w, AdjListNetworkArc<WeightType>*next){adjVex = v;weight = w;nextarc = next;}//定义有向网邻接表中顶点结点的类模板template <class ElemType, class WeightType>struct AdjListNetworkVex{ElemType data;//顶点信息AdjListNetworkArc<WeightType> *firstarc;//链表头指针AdjListNetworkVex();AdjListNetworkVex(ElemType val,AdjListNetworkArc<WeightType> *adj = NULL);};template <class ElemType, class WeightType>AdjListNetworkVex<ElemType, WeightType>::AdjListNetworkVex(){firstarc = NULL;}template <class ElemType, class WeightType>AdjListNetworkVex<ElemType, WeightType>::AdjListNetworkVex(ElemType val,AdjListNetworkArc<WeightType> *adj){data = val;firstarc = adj;}//有向图邻接表类模板的定义template<class ElemType, class WeightType>class AdjListDirNetwork{protected:int vexNum;//顶点结点的个数int vexMaxNum;//允许的顶点最大数目int arcNum;//弧数AdjListNetworkVex<ElemType, WeightType>*vexTable;//顶点表mutable Status*tag;//标志数组WeightType infinity;//无穷大值public:AdjListDirNetwork(ElemType es[], int vertexNum, int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFAULTY);AdjListDirNetwork(int vertexMaxNum = DEFAULT_SIZE, WeightType infinit = (WeightType)DEFAULT_INFAULTY);~AdjListDirNetwork() {}int GetVexNum()const;//求有向网的顶点个数int GetArcNum()const;//求有向网的弧数个数int GetOrder(ElemType&d)const;//求顶点的序号WeightType GetInfinity()const;//取无穷大的值WeightType GetWeight(int v1, int v2)const;//取从顶点为v1到v2的弧的权值Status GetElem(int v, ElemType&e)const;//求顶点的元素值Status GetTag(int v)const;//求顶点v的标志void SetTag(int v, Status tag)const;//修改顶点v的标志void InsertVex(const ElemType&d);//插入元素值为d的顶点void InsertArc(int v1, int v2, WeightType w);//插入从v1到v2、权为w的弧int FirstAdjVex(int v)const;//求顶点v的第一个邻接点序号int NextAdjVex(int v1, int v2)const;//求顶点v1的相对于v2的下一个邻接点};template<class ElemType, class WeightType>AdjListDirNetwork<ElemType, WeightType>::AdjListDirNetwork(int vertexMaxNum, WeightType infinit){if (vertexMaxNum < 0)cerr<<"允许的顶点最大数目不能为负!";vexNum = 0;vexMaxNum = vertexMaxNum;arcNum = 0;infinity = infinit;tag = new Status[vexMaxNum];vexTable = new AdjListNetworkVex<ElemType, WeightType>[vexMaxNum];}template<class ElemType, class WeightType>AdjListDirNetwork<ElemType, WeightType>::AdjListDirNetwork(ElemType es[], int vertexNum, int vertexMaxNum, WeightType infinit){if (vertexNum < 0)cerr << "允许的顶点最大数目不能为负!";if (vertexMaxNum < vexNum)cerr << "顶点数目不能大于允许的顶点最大数目!";vexMaxNum = vertexMaxNum;vexNum = vertexNum;arcNum = 0;infinity = infinit;tag = new Status[vexMaxNum];vexTable = new AdjListNetworkVex<ElemType, WeightType>[vexMaxNum];for (int v = 0; v < vexNum; v++){tag[v] = UNVISITED;vexTable[v].data = es[v];vexTable[v].firstarc = NULL;}}template<class ElemType,class WeightType>int AdjListDirNetwork<ElemType, WeightType>::GetVexNum()const{return vexNum;}template<class ElemType, class WeightType>int AdjListDirNetwork<ElemType, WeightType>::GetArcNum()const{return arcNum;}template<class ElemType, class WeightType>int AdjListDirNetwork<ElemType, WeightType>::GetOrder(ElemType&d)const{for (int i = 0; i < vexNum; i++)if (vexTable[i].data == d)return i;}、template<class ElemType,class WeightType>void AdjListDirNetwork<ElemType, WeightType>::InsertArc(int v1, int v2, WeightType w){if (v1 < 0 || v1 >= vexNum)cerr<<"v1不合法!";if (v2 < 0 || v2 >= vexNum)cerr<<"v2不合法!";if (v1 == v2)cerr<<"v1不能等于v2!";if (w == infinity)cerr<<"w不能为无穷大!";AdjListNetworkArc<WeightType>*p;p = vexTable[v1].firstarc;vexTable[v1].firstarc =new AdjListNetworkArc<WeightType>(v2, w, p);arcNum++;}//******************************创建图************************************************// template<class ElemType, class WeightType>bool LoadData(AdjListDirNetwork<ElemType, WeightType> &graph){//读取文件信息并赋值变量ifstream read("d:\\GraphData.txt");if (!read){cout << "File open error!\n";return 0;}int vexNum, arcNum;read >> vexNum >> arcNum;char*es;es = new char[vexNum];for (int i = 0; i < vexNum; i++)read >> es[i];int **arcTable;arcTable = new int*[arcNum];for (int i = 0; i <arcNum; i++)arcTable[i] = new int[3];for (int i = 0; i < arcNum; i++){for (int j = 0; j < 3; j++)read >> arcTable[i][j];}//开始创建有向图for (int i = 0; i < vexNum; i++)//插入顶点信息{graph.InsertVex(es[i]);}for (int i = 0; i < arcNum; i++)//插入弧结点信息{graph.InsertArc(arcTable[i][0],arcTable[i][1],arcTable[i][2]);}read.close();return 1;//创建完成}//***************************深度优先搜索*********************************//template <class ElemType, class WeightType>void DFS(AdjListDirNetwork<ElemType, WeightType> &graph, int v, void(*Visit)(const ElemType &)) {ElemType e;graph.SetTag(v, VISITED); //设置顶点v 已访问标记graph.GetElem(v, e); //取顶点v的数据元素Visit(e);//访问顶点vfor (int w = graph.FirstAdjVex(v); w != -1; w = graph.NextAdjVex(v, w))if (graph.GetTag(w) == UNVISITED)DFS(graph, w, Visit);//从v的邻接点w开始深度优先搜索}//对图graph进行深度优先遍历template <class ElemType, class WeightType>void DFSTraverse(AdjListDirNetwork<ElemType, WeightType> &graph, void(*Visit)(const ElemType &)){int v;for (v = 0; v<graph.GetVexNum(); v++)//设置未访问标志graph.SetTag(v, UNVISITED);//逐个判断顶点,从未访问顶点开始深度优先搜索for (v = 0; v<graph.GetVexNum(); v++)if (graph.GetTag(v) == UNVISITED)DFS(graph, v, Visit);}//**********************判断两点间是否存在路径(深度搜索)*************************************************template<class ElemType, class WeightType>bool PathDFS(AdjListDirNetwork<ElemType, WeightType> &graph, int start, int end){graph.SetTag(start, VISITED);for (int v = graph.FirstAdjVex(start); v != -1; v = graph.NextAdjVex(start, v))if (graph.GetTag(v) == UNVISITED){if (v == end)return 1;PathDFS(graph, v, end);}else return 0;}template<class ElemType, class WeightType>bool ExistPathDFS(AdjListDirNetwork<ElemType, WeightType> &graph, ElemType start, ElemType end){for (int v = 0; v < graph.GetVexNum(); v++)graph.SetTag(v, UNVISITED);int StartNum = graph.GetOrder(start);int EndNum = graph.GetOrder(end);return PathDFS(graph, StartNum, EndNum);}//*****************************广度优先搜索**********************************************////从顶点v开始广度优先搜索template <class ElemType, class WeightType>void BFS(AdjListDirNetwork<ElemType, WeightType> &graph, int v, void(*Visit)(const ElemType &)){LinkQueue<int> q;int u, w;ElemType e;graph.SetTag(v, VISITED); //设置访问标志graph.GetElem(v, e);//取顶点v的数据元素值Visit(e);//访问顶点vq.EnQueue(v);//顶点v入队while (!q.IsEmpty()){q.DelQueue(u);//队头顶点u出队//逐个判断u的邻接点,若未访问则访问之并入队for (w = graph.FirstAdjVex(u); w != -1; w = graph.NextAdjVex(u, w))if (graph.GetTag(w) == UNVISITED){graph.SetTag(w, VISITED);graph.GetElem(w, e);Visit(e);q.EnQueue(w);}}}//对图graph进行广度优先遍历template <class ElemType, class WeightType>void BFSTraverse(AdjListDirNetwork<ElemType, WeightType> &graph, void(*Visit)(const ElemType &)){int v;for (v = 0; v<graph.GetVexNum(); v++)//设置未访问标志graph.SetTag(v, UNVISITED);//逐个判断顶点,从未访问顶点开始广度优先搜索for (v = 0; v<graph.GetVexNum(); v++)if (graph.GetTag(v) == UNVISITED)BFS(graph, v, Visit);}//**********************判断两点间是否存在路径(广度搜索)*************************************************template <class ElemType, class WeightType>bool PathBFS(AdjListDirNetwork<ElemType, WeightType> &graph, int v,int end){LinkQueue<int> q;int u, w;graph.SetTag(v, VISITED); //设置访问标志q.EnQueue(v);//顶点v入队while (!q.IsEmpty()||w==end){q.DelQueue(u);//队头顶点u出队//逐个判断u的邻接点,若未访问则访问之并入队for (w = graph.FirstAdjVex(u); w != -1; w = graph.NextAdjVex(u, w))if (graph.GetTag(w) == UNVISITED){graph.SetTag(w, VISITED);q.EnQueue(w);}}if (graph.GetTag(end) == UNVISITED)return 0;else return 1;}void Display(const char &e){cout << e << " ";}void main(void){AdjListDirNetwork<char, int> graph(20, 9999);char start, end;//从文件GraphData.txt中读取有向图数据,建立图graphif (!LoadData(graph)){cout << "图建立失败!" << endl;exit(1);}cout << "图的深度优先遍历序列为:";DFSTraverse(graph, Display);cout << endl;cout << "图的广度优先遍历序列为:";BFSTraverse(graph, Display);cout << endl;//-----------------------------以下测试第1题------------------------------------------------cout << "请输入路径的起点名称(A):";cin >> start;//输入:Acout << "请输入路径的终点名称(G):";cin >> end;//输入:Gif (ExistPathDFS(graph, start, end))//------------------调用第1题函数-------------------------- cout << "按照深度优先搜索策略判断:" << start << "与" << end << "存在路径!" << endl;elsecout << "按照深度优先搜索策略判断:" << start << "与" << end << "不存在路径!" << endl;//-----------------------------以下测试第2题------------------------------------------------cout << "请输入路径的起点名称(A):";cin >> start;//输入:Acout << "请输入路径的终点名称(H):";cin >> end;//输入:Hif (ExistPathBFS(graph, start, end))//------------------调用第2题函数--------------------------cout << "按照广度优先搜索策略判断:" << start << "与" << end << "存在路径!" << endl;elsecout << "按照广度优先搜索策略判断:" << start << "与" << end << "不存在路径!" << endl;//-----------------------------以下测试第3题------------------------------------------------cout << "请输入计算最短路径的起点名称(A):";cin >> start;//输入:Aint *path = new int[graph.GetVexNum()], *dist = new int[graph.GetVexNum()];ShortestPathDij(graph, graph.GetOrder(start), path, dist);OutputShortestPathDij(graph, graph.GetOrder(start), path, dist);//调用OutputShortestPathDij函数输出结果,请自己实现delete[]path;delete[]dist;system("pause");}五、实验小结实验让我受益匪浅。

相关文档
最新文档