Java实现无向图的建立与遍历
2020-12-09 23:33
标签:定义 查找 输出 属性 lse 结构 string 表示法 邻接表 邻接矩阵是一种利用一维数组记录点集信息、二维数组记录边集信息来表示图的表示法,因此我们可以将图抽象成一个类,点集信息和边集信息抽象成类的属性,就可以在Java中描述出来,代码如下: 每一个具体的图,就是该类的一个实例化对象,因此我们可以在构造函数中实现图的创建,代码如下: 创建好图后,我们还要实现图的遍历。由于图已经被我们抽象成一个类,因此我们可以将图的遍历定义成类的方法。对于连通图,调用遍历算法后即可访问所有结点,但对于非连通图,调用遍历算法后仍有一些结点没有被访问,需要从图中另选一个未被访问的顶点再次调用遍历算法。因此需要附设一个访问标志数组visited[n],来记录被访问的结点。增加了访问标志数组的类属性如下: 图的遍历分为深度优先遍历和广度优先遍历,接下来我们来分别实现它们。深度优先遍历代码如下: 广度优先遍历代码如下: 以上基于邻接矩阵表示法的无向图的类就定义好了,接着我们在客户端里使用即可: 邻接表是一种基于链式存储结构的表示法。在邻接表中,对图的每个顶点建立一个单链表,单链表的第一个结点存放顶点信息,称为点结点,其余结点存放边信息,称为边结点。此外,还需要一个顶点数组,存储对所有单链表的引用。因此我们需要定义三个类,第一个类为顶点类,用来生成点结点;第二个类为边类,用来生成边结点;第三个类为图类,里面定义有属性——顶点数组和方法——图的遍历。代码如下: 同样的,我们在构造方法中进行图的建立,代码如下: 接着实现图的遍历,同样需要附设一个访问标志数组,因此将图类属性修改如下: 深度优先遍历: 广度优先遍历: 客户端代码如下: 以上虽然只实现了无向图,但其实有向图、无向网、有向网的建立和遍历都同理,只需将代码稍作修改,在边信息中增加权值信息,用对称边记录反方向的边即可。 Java实现无向图的建立与遍历 标签:定义 查找 输出 属性 lse 结构 string 表示法 邻接表 原文地址:https://www.cnblogs.com/ysyasd/p/10992055.html一、基于邻接矩阵表示法的无向图
1 class AMGraph{
2
3 private String[] vexs = null; //点集信息
4
5 private int[][] arcs = null; //边集信息
6
7 }
1 public AMGraph(int vexNum,int arcNum) { //输入点的个数和边的个数
2
3 this.vexs = new String[vexNum];
4 this.arcs = new int[vexNum][vexNum];
5
6 System.out.print("请依次输入顶点值,以空格隔开:");
7 Scanner sc = new Scanner(System.in);
8 for(int i = 0; i //根据输入建立点集
9 this.vexs[i] = sc.next();
10 }
11
12 for(int i = 0; i //初始化边集
13 for(int j = 0; j ) {
14 this.arcs[i][j] = 0; //0表示该位置所对应的两顶点之间没有边
15 }
16 }
17
18 start:for(int i = 0; i //开始建立边集
19
20 sc = new Scanner(System.in);
21 int vex1Site = 0;
22 int vex2Site = 0;
23 String vex1 = null;
24 String vex2 = null;
25
26 System.out.print("请输入第" + (i+1) + "条边所依附的两个顶点,以空格隔开:");
27 vex1 = sc.next();
28 vex2 = sc.next();
29 for(int j = 0; j this.vexs.length; j++) { //查找输入的第一个顶点的位置
30 if (this.vexs[j].equals(vex1)) {
31 vex1Site = j;
32 break;
33 }
34 if (j == this.vexs.length - 1) {
35 System.out.println("未找到第一个顶点,请重新输入!");
36 i--;
37 continue start;
38 }
39 }
40 for (int j = 0; j this.vexs.length; j++) { //查找输入的第二个顶点的位置
41 if(this.vexs[j].equals(vex2)) {
42 vex2Site = j;
43 break;
44 }
45 if (j == this.vexs.length - 1) {
46 System.out.println("未找到第二个顶点,请重新输入!");
47 i--;
48 continue start;
49 }
50 }
51 if(this.arcs[vex1Site][vex2Site] != 0) { //检测该边是否已经输入
52 System.out.println("该边已存在!");
53 i--;
54 continue start;
55 }else {
56 this.arcs[vex1Site][vex2Site] = 1; //1表示该位置所对应的两顶点之间有边
57 this.arcs[vex2Site][vex1Site] = 1; //对称边也置1
58 }
59 }
60 System.out.println("基于邻接矩阵的无向图创建成功!");
61 sc.close();
62 }
1 class AMGraph{
2
3 private String[] vexs = null;
4
5 private int[][] arcs = null;
6
7 private boolean[] visited = null; //false表示该位置的顶点未访问,true表示已访问
8
9 }
1 public void dFSTraverse() {
2
3 this.visited = new boolean[this.vexs.length]; //初始化访问标志数组
4 for(int i = 0; i this.visited.length; i++) {
5 this.visited[i] = false;
6 }
7
8 for(int i = 0; i this.visited.length; i++) {
9 if(!this.visited[i]) { //对未访问的顶点调用深度优先遍历算法
10 dFS_AM(i);
11 }
12 }
13 }
1 public void dFS_AM(int site) { //输入深度优先遍历的开始顶点
2 System.out.println(this.vexs[site]); //输出该顶点
3 this.visited[site] = true; //置访问标志为true
4 for(int i = 0; i this.vexs.length; i++) { //依次查找未访问邻接点,并以该邻接点为始点调用深度优先遍历算法
5 if(this.arcs[site][i] != 0 && !this.visited[i]) {
6 this.dFS_AM(i);
7 }
8 }
9 }
1 public void bFSTraverse() {
2
3 this.visited = new boolean[this.vexs.length]; //初始化访问标志数组
4 for(int i = 0; i this.visited.length; i++) {
5 this.visited[i] = false;
6 }
7
8 for(int i = 0; i this.visited.length; i++) {
9 if(!this.visited[i]) { //对未访问的顶点调用广度优先遍历算法
10 bFS_AM(i);
11 }
12 }
13 }
1 public void bFS_AM(int site) { //输入开始顶点
2 System.out.println(this.vexs[site]); //输出该顶点
3 this.visited[site] = true; //置访问标志为true
4 LinkedList
1 public class Main {
2
3 public static void main(String[] args) {
4
5 Scanner sc = new Scanner(System.in);
6 int vexNum = 0;
7 int arcNum = 0;
8 while(true) {
9 System.out.print("请输入要建立无向图的总顶点数和总边数,以空格隔开:");
10 try {
11 vexNum = sc.nextInt();
12 arcNum = sc.nextInt();
13 break;
14 } catch (Exception e) {
15 System.out.println("输入不合法!");
16 continue;
17 }
18 }
19
20 AMGraph aMGraph = new AMGraph(vexNum, arcNum);
21 System.out.println("由深度优先遍历得:");
22 aMGraph.dFSTraverse();
23 System.out.println("由广度优先遍历得:");
24 aMGraph.bFSTraverse();
25
26 sc.close();
27 }
28
29 }
二、基于邻接表表示法的无向图
1 class ALGraph_Head{ //顶点类
2
3 private String data = null; //点结点值
4
5 private ALGraph_Arc firstArc= null; //第一条边的指针
6
7 public String getData() {
8 return data;
9 }
10
11 public ALGraph_Arc getFirstArc() {
12 return firstArc;
13 }
14
15 public void setFirstArc(ALGraph_Arc firstArc) {
16 this.firstArc = firstArc;
17 }
18
19 public ALGraph_Head(String data) {
20 this.data = data;
21 }
22 }
1 class ALGraph_Arc{ //边类
2
3 private int adjVexSite = 0; //该边所连接的顶点的邻接点的位置
4
5 private ALGraph_Arc nextArc = null; //下一条边的指针
6
7 public int getAdjVexSite() {
8 return adjVexSite;
9 }
10
11 public ALGraph_Arc getNextArc() {
12 return nextArc;
13 }
14
15 public ALGraph_Arc(int adjVexSite, ALGraph_Arc nextArc) {
16 this.adjVexSite = adjVexSite;
17 this.nextArc = nextArc;
18 }
19 }
1 class ALGraph{ //图类
2
3 private ALGraph_Head[] aLGraph_Heads = null; //顶点数组
4
5 }
1 public ALGraph(int vexNum,int arcNum) { //输入顶点个数,边的个数
2
3 this.aLGraph_Heads = new ALGraph_Head[vexNum];
4
5 System.out.print("请依次输入顶点值,以空格隔开:");
6 Scanner sc = new Scanner(System.in);
7 for(int i = 0; i //建立顶点数组存储点结点
8 this.aLGraph_Heads[i] = new ALGraph_Head(sc.next());
9 }
10
11 start:for(int i = 0; i //开始存储边信息
12
13 sc = new Scanner(System.in);
14 int vex1Site = 0;
15 int vex2Site = 0;
16 String vex1 = null;
17 String vex2 = null;
18
19 System.out.print("请输入第" + (i+1) + "条边所依附的两个顶点,以空格隔开:");
20 vex1 = sc.next();
21 vex2 = sc.next();
22 for(int j = 0; j this.aLGraph_Heads.length; j++) { //查找第一个顶点的位置
23 if (this.aLGraph_Heads[j].getData().equals(vex1)) {
24 vex1Site = j;
25 break;
26 }
27 if (j == this.aLGraph_Heads.length - 1) {
28 System.out.println("未找到第一个顶点,请重新输入!");
29 i--;
30 continue start;
31 }
32 }
33 for (int j = 0; j this.aLGraph_Heads.length; j++) { //查找第二个顶点的位置
34 if(this.aLGraph_Heads[j].getData().equals(vex2)) {
35 vex2Site = j;
36 break;
37 }
38 if (j == this.aLGraph_Heads.length - 1) {
39 System.out.println("未找到第二个顶点,请重新输入!");
40 i--;
41 continue start;
42 }
43 }
44 ALGraph_Arc aLGraph_Arc = this.aLGraph_Heads[vex1Site].getFirstArc(); //获取点结点里的边指针
45 while(aLGraph_Arc != null) { //判断边是否已存储
46 if(aLGraph_Arc.getAdjVexSite() == vex2Site) {
47 System.out.println("该边已存在!");
48 i--;
49 continue start;
50 }
51 aLGraph_Arc = aLGraph_Arc.getNextArc();
52 }
53 this.aLGraph_Heads[vex1Site].setFirstArc(new ALGraph_Arc(vex2Site, this.aLGraph_Heads[vex1Site].getFirstArc())); //将边结点加入单链表中
54 this.aLGraph_Heads[vex2Site].setFirstArc(new ALGraph_Arc(vex1Site, this.aLGraph_Heads[vex2Site].getFirstArc())); //对称边结点也加入单链表
55 }
56 System.out.println("基于邻接表的无向图创建成功!");
57 sc.close();
58 }
1 class ALGraph{
2
3 private ALGraph_Head[] aLGraph_Heads = null;
4
5 private boolean[] visited = null; //访问标志数组
6
7 }
1 public void dFSTraverse() {
2
3 this.visited = new boolean[this.aLGraph_Heads.length]; //建立并初始化访问标志数组
4 for(int i = 0; i this.visited.length; i++) {
5 this.visited[i] = false;
6 }
7
8 for(int i = 0; i this.visited.length; i++) { //以未访问的点为始点调用深度优先遍历算法
9 if(!this.visited[i]) {
10 dFS_AM(i);
11 }
12 }
13 }
1 public void dFS_AM(int site) {
2 System.out.println(this.aLGraph_Heads[site].getData()); //输出点值
3 this.visited[site] = true; //置访问标志为true
4 ALGraph_Arc aLGraph_Arc = this.aLGraph_Heads[site].getFirstArc(); //获取点结点中的边指针
5 while(aLGraph_Arc != null) {
6 if(!visited[aLGraph_Arc.getAdjVexSite()]) { //如果该边所连接的顶点的邻接点未访问,则以该邻接点为始点调用深度优先遍历算法
7 this.dFS_AM(aLGraph_Arc.getAdjVexSite());
8 }
9 aLGraph_Arc = aLGraph_Arc.getNextArc(); //获取下一条边
10 }
11 }
1 public void bFSTraverse() {
2
3 this.visited = new boolean[this.aLGraph_Heads.length]; //建立并初始化访问标志数组
4 for(int i = 0; i this.visited.length; i++) {
5 this.visited[i] = false;
6 }
7
8 for(int i = 0; i this.visited.length; i++) { //以未访问的点为始点调用广度优先遍历算法
9 if(!this.visited[i]) {
10 bFS_AM(i);
11 }
12 }
13 }
1 public void bFS_AM(int site) {
2 System.out.println(this.aLGraph_Heads[site].getData()); //输出点值
3 this.visited[site] = true; //置访问标志为true
4 LinkedList
1 public class Main {
2
3 public static void main(String[] args) {
4
5 Scanner sc = new Scanner(System.in);
6 int vexNum = 0;
7 int arcNum = 0;
8 while(true) {
9 System.out.print("请输入要建立无向图的总顶点数和总边数,以空格隔开:");
10 try {
11 vexNum = sc.nextInt();
12 arcNum = sc.nextInt();
13 break;
14 } catch (Exception e) {
15 System.out.println("输入不合法!");
16 continue;
17 }
18 }
19
20 ALGraph aLGraph = new ALGraph(vexNum, arcNum);
21 System.out.println("由深度优先遍历得:");
22 aLGraph.dFSTraverse();
23 System.out.println("由广度优先遍历得:");
24 aLGraph.bFSTraverse();
25
26 sc.close();
27 }
28
29 }
三、小结
上一篇:Java开发环境之Eclipse
下一篇:多线程