图和图的遍历算法

1.存储结构(邻接链表)

1.1每个顶点用VexNode类表示,每条边用ArcNode表示

1.2所有顶点用数组VexNode adjlist[]表示,所有邻接顶点用链表表示

2.遍历算法

2.1深度优先遍历DFS

用递归实现,从V0开始,访问V0即邻接顶点V1,访问V1及其邻接顶点...

2.2广度优先遍历

用队列实现,从V0开始,访问V0,入队,出队,访问V0所有临界点,入队...直到队列为空

Graph.java

  1 package com.gxf.graph;
  2
  3 /**
  4  * 定义一个图类
  5  * 包过构造方法
  6  * 插入顶点
  7  * 插入边
  8  * 深度优先遍历
  9  * 广度优先遍历
 10  * @author Administrator
 11  *
 12  */
 13 public class Graph {
 14     int n;
 15     int max;//当前顶点数和最大定点数
 16     VexNode adjlist[];//邻接链表存储结构
 17     boolean visited[];//标记顶点访问状态
 18
 19     /**
 20      * 构造一个长度为l的邻接链表
 21      * @param l
 22      */
 23     public Graph(int l){
 24         n = 0;
 25         max = l;
 26         adjlist = new VexNode[l];
 27         visited = new boolean[l];
 28     }
 29
 30     /**
 31      * 递归调用实现深度优先遍历
 32      * @param v0待遍历结点
 33      * @param vs访问函数类对象
 34      */
 35     public void dfs0(int v0, Visit vs){
 36         ArcNode p = adjlist[v0].firstArc;//node边结点
 37
 38         if(!visited[v0]){//结点没有被访问过
 39             vs.visit(v0);//访问这个结点
 40             visited[v0] = true;//标记结点已经被访问
 41         }
 42         while(null != p){
 43             int v = p.adjvex;
 44             if(!visited[v])
 45                 dfs0(v, vs);//邻接顶点没有被访问,深度访问该顶点
 46             p = p.next;//深度访问结束,回退访问下一个邻接顶点
 47         }
 48     }
 49
 50     /**
 51      * 向类的调用者提供一个调用接口
 52      * 初始化visited[]
 53      * 调用dfs0(int, vs)
 54      * @param v0
 55      * @param vs
 56      */
 57     public void dfs(int v0, Visit vs){
 58         for(int i = 0; i < max; i++){
 59             visited[i] = false;
 60         }//初始化visited[]数组
 61         dfs0(v0, vs);
 62     }
 63
 64     /**
 65      * 广度优先遍历
 66      * 邻接链表用的是数组存储,只要用int节可以找到v0对应的顶点
 67      * @param v0
 68      * @param vs
 69      */
 70     public void bfs(int v0, Visit vs){
 71         int front = 0;
 72         int rear = 0;//队列头尾指针初始化为0
 73         int queue[] = new int[100];//队列
 74         int headVex;
 75
 76         //没有递归调用可以初始化visited[]数组
 77         for(int i = 0; i < max; i++){
 78             visited[i] = false;
 79         }
 80
 81         vs.visit(v0);
 82         visited[v0] = true;//访问v0顶点,访问过的顶点入队,队列里所有顶点都是访问过的
 83         queue[rear++] = v0;//顶点入队
 84
 85         while(front != rear){//队列不为空
 86             headVex = queue[front++];//出队 队列里面都是访问过的顶点
 87             ArcNode firstArc = adjlist[headVex].firstArc;//第一条边结点
 88             while(null != firstArc){//边结点不为空,有邻接点
 89                 if(!visited[firstArc.adjvex]){//邻接顶点没有被访问过
 90                     vs.visit(firstArc.adjvex);//访问邻接顶点
 91                     visited[firstArc.adjvex] = true;
 92                     queue[rear++] = firstArc.adjvex;//入队
 93                 }
 94                 firstArc = firstArc.next;//下一个邻接顶点
 95             }
 96         }
 97     }
 98     /**
 99      * 向图中插入一个顶点
100      * @param data
101      */
102     public void insertVex(int data){
103         if(n < max){//没有超过最大定点数
104             VexNode vexInsert = new VexNode();
105             vexInsert.data = data;
106             adjlist[n++] = vexInsert;
107             vexInsert.firstArc = null;
108             //n++;
109         }
110     }
111
112     /**
113      * 在顶点v0和v1中间插入一条边结点
114      * 在v0和v1的链表中都需要插入一个边结点
115      * @param v0
116      * @param v1
117      */
118     public void insertEdge(int v0, int v1){
119         ArcNode arcNode0 = new ArcNode();//插入v0链表中的边结点
120         ArcNode arcNode1 = new ArcNode();//插入v1链表中的边结点
121
122         VexNode vex0 = adjlist[v0];
123
124         VexNode vex1 = adjlist[v1];
125
126         arcNode0.next = vex0.firstArc;
127         arcNode1.next = vex1.firstArc;
128
129         vex0.firstArc = arcNode0;
130         vex1.firstArc = arcNode1;//采用头插法插入到链表中
131
132         arcNode0.adjvex = v1;
133         arcNode1.adjvex = v0;
134     }
135 }

VexNode.java

 1 package com.gxf.graph;
 2
 3 /**
 4  * 邻接链表中顶点类
 5  * data结点内容
 6  * firstArc第一条边结点
 7  * @author Administrator
 8  *
 9  */
10 public class VexNode {
11     int data;
12     ArcNode firstArc;
13
14 }
15 /**
16  * 邻接链表中边结点类
17  * 一条边对应一个ArcNode
18  * adjnode邻接顶点
19  * next下一条边
20  * @author Administrator
21  *
22  */
23 class ArcNode{
24     int adjvex;
25     ArcNode next;
26 }

Visit.java

 1 package com.gxf.graph;
 2
 3 public class Visit {
 4     public String nodeString;
 5     public Visit(){
 6         nodeString = new String();
 7     }
 8
 9     public void visit(int v){
10         nodeString += v + " ";
11 //        System.out.print(v + " ");
12     }
13     public String toString(){
14         return nodeString;
15     }
16 }

Test.java

 1 package com.gxf.graph;
 2
 3 /**
 4  * 测试图的DFS和BFS
 5  * 插入四个顶点
 6  * 插入边形成连通图
 7  * @author Administrator
 8  *
 9  */
10 public class Test {
11
12     public static void main(String[] args) {
13         Graph graph = new Graph(10);//创建四个顶点的图
14         Visit visit = new Visit();
15         //插入四个顶点
16         for(int i = 0; i < 4; i++){
17             graph.insertVex(i);
18         }
19         //插入边
20         graph.insertEdge(0, 1);
21         graph.insertEdge(1, 2);
22         graph.insertEdge(2, 3);
23         graph.insertEdge(3, 0);//插入四条边,形成连通图
24         System.out.println("深度优先遍历:");
25         graph.dfs(0, visit);
26 //        System.out.println();
27         System.out.println(visit.toString());
28         System.out.println("广度优先遍历:");
29         visit = new Visit();
30         graph.bfs(0, visit);
31         System.out.println(visit.toString());
32
33     }
34
35 }

时间: 2024-10-16 01:20:16

图和图的遍历算法的相关文章

图的遍历算法

1.连通图的宽度优先搜索(BFS) (1)算法思路 准备:起点v 和一个空队列Q . ①  将v 打上已访问标记,并将 v 放入队列Q . ②   取出队列 Q 的 队首元素   u ,搜索所有与 u 相邻的顶点.如果 w 与u 相邻且未访问, 则将w 打     上已访问标记,并将 w 放入队列Q . ③  重复②,直到队列Q 空 (2)算法代码: (3)复杂性分析 (4)宽度优先生成树 2.一般图的宽度优先遍历 3.连通图的深度优先搜索(DFS) (3)深度优先生成树

实验四 图的遍历算法设计与实现

一.实验名称:图的遍历算法设计与实现 二.实验目的: 1.掌握图的深度优先遍历的算法. 2.掌握图的广度优先遍历的算法. 3.实验章节:算法设计与分析 第四章 三.实验内容.实验问题和程序运行结果 第一部分 广度优先遍历算法 1. 分析Graph类,画出Graph类初始化以后的Graph对象的数据结构图. 2. 分析BFS函数,画出流程图. 3. 上述程序   int data[7][7]={{ 1,-1,-1,-1,-1,-1,-1}, { 6, 3, 2,-1,-1,-1,-1}, { 0,

数据结构算法之图的存储与遍历(Java)

一:图的分类 1:无向图 即两个顶点之间没有明确的指向关系,只有一条边相连,例如,A顶点和B顶点之间可以表示为 <A, B> 也可以表示为<B, A>,如下所示 2:有向图 顶点之间是有方向性的,例如A和B顶点之间,A指向了B,B也指向了A,两者是不同的,如果给边赋予权重,那么这种异同便更加显著了 =============================================================================================

【图】实验题二:实现图的遍历算法

递归深度优先遍历算法 1 #include<stdio.h> 2 #include<malloc.h> 3 #define MAXV 100 4 #define INF 32767 5 typedef struct ANode 6 { 7 int adjvex; 8 int weight; 9 struct ANode *nextarc; 10 } ArcNode; 11 12 typedef struct 13 { 14 int count; 15 ArcNode *firsta

图的遍历算法:DFS、BFS

在图的基本算法中,最初需要接触的就是图的遍历算法,根据访问节点的顺序,可分为深度优先搜索(DFS)和广度优先搜索(BFS). DFS(深度优先搜索)算法 Depth-First-Search 深度优先算法,是一种用于遍历或搜索树或图的算法.沿着树的深度遍历树的节点,尽可能深的搜索树的分支. 当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点. 这一过程一直进行到已发现从源节点可达的所有节点为止. 如果还存在未被发现的节点, 则选择其中一个作为源节点并重复以上过程,整个进程反复

图的表示、深度广度遍历算法及其应用

世间的一切对象都可化为节点:世间一切关系都可化为节点间的一条线:从而组成了如梦幻泡影的图.将来的环球必定是图的世界. 一.图的表示 图有有向图和无向图,表示方法一般有邻接表.邻接矩阵等方法,无向图和有向图都可以用这两种方法表示. 图1. 图的例子[1] 1.邻接表 在邻接表中,对于每个顶点u,使用一个链表把所有与u相邻的点点串起来,并标记这个集合为adj(u).举个栗子如下: 图2. 邻接表表示图的例子[1] 在真正操作图进行实验的时候,一般也都使用邻接矩阵表示,例如要存储图1中的有向图,可以直

数据结构实验报告-实验四 图的构造与遍历

实验四   图的构造与遍历   l  实验目的 1.图的的定义和遍历 (1)掌握图的邻接矩阵.邻接表的表示方法. (2)掌握建立图的邻接矩阵的算法. (3)掌握建立图的邻接表的算法. (4)加深对图的理解,逐步培养解决实际问题的能力. l  实验内容 1.图的定义和遍历 (一)基础题 1.编写图基本操作函数: (1)CreateALGraph(ALGraph &G) 建立无向图的邻接表表示: (2)LocateVex(ALGraph &G,char v)图查找信息: (3)DFSTrave

图的非连通遍历

1.连通图和非连通图 连通图:任意的一个顶点到任意的另外一个顶点都有着相应的路径所能够到达. 非连通图:只要找出了有一个顶点不能够到达另外一个顶点. 2.遍历 对于连通图来说,通过DFS或BFS就可以完成遍历: 对于非连通图来说,就得从每个顶点出发进行搜索,每一次的从一个新的顶点出发访问,每个顶点都要开始搜索一遍. 3.非连通图的遍历算法 (1).不可取的算法:没有必要将非连通图生成森林,在由森林生成我们的遍历树,然后再进行树形结构的访问. (2).比较好的算法:直接调动我们之前编写好的DFS(

数据结构之图(存储结构、遍历)

新学期开始了,开始专心于技术上了,上学期的寒假总是那么短暂,飘飘乎就这样逝去,今天补补上学期还没学完的数据结构---图,希望能和大家一起探讨,共同进步~ 定义: 图是由顶点集合及顶点间的关系集合组成的一种数据结构. 图的存储结构: 1.1 邻接矩阵 图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 看一个实例,下图左就是一个无向图. 从上面可以看出,无向图的边数组是一