无向图--邻接矩阵、连接矩阵、深度遍历、广度遍历、生成树
2015-09-15 13:46
573 查看
![](http://img2.ph.126.net/sEgIJq8fUvqvf1M4SbLYUg==/6630421252863192332.png)
1、开始生成的无向图
![](http://img1.ph.126.net/vz63Thb33-guSgCRhzIVVQ==/6631404216257626183.png)
2、由图深度优先遍历生成的树
package graph; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Stack; public class GraphTest { public static void main(String[] args) { AdjacencyMatrixGraph a = new AdjacencyMatrixGraph(6); a.addVertex("A"); a.addVertex("B"); a.addVertex("C"); a.addVertex("D"); a.addVertex("E"); a.addVertex("F"); a.addEdge(0, 1); a.addEdge(1, 2); a.addEdge(0, 3); a.addEdge(2, 4); a.addEdge(0, 2); a.addEdge(0, 4); a.addEdge(3, 5); a.printMatrix(); a.traverseDepth(); System.out.println(); a.traverseBroad(); System.out.println(); a.growMinTree(); System.out.println(); a.traverseBroad(); // ConnectionMatrixGraph con = new ConnectionMatrixGraph(); // con.addVertex("A"); // con.addVertex("B"); // con.addVertex("C"); // con.addVertex("D"); // // con.addEdge(0, 1); // con.addEdge(0, 3); // con.addEdge(1, 2); // con.addEdge(0, 2); // con.addEdge(2, 3); // // con.printConnectionMatrix(); // con.traverseBroad(); } } /** * 采用邻接矩阵的无向图 * @author LiangYH * */ class AdjacencyMatrixGraph{ //最大顶点数的容量 private int maxSize; //存放顶点 private List<Vertex> vertexList; //邻接矩阵,存放点和点的关系 private int[][] adjacencyMatrix; public AdjacencyMatrixGraph(int maxSize){ this.maxSize = maxSize; this.vertexList = new ArrayList<Vertex>(); adjacencyMatrix = new int[maxSize][maxSize]; } public boolean isFull(){ return vertexList.size() >= maxSize; } //增加顶点 public void addVertex(String label){ if(isFull()) throw new ArrayIndexOutOfBoundsException("数组已经满了"); vertexList.add(new Vertex(label)); } //增加边 public void addEdge(int vertexIndex1, int vertexIndex2){ int size = getSize(); if(vertexIndex1 >= size || vertexIndex2 >= size) throw new ArrayIndexOutOfBoundsException(); this.adjacencyMatrix[vertexIndex1][vertexIndex2] = 1; this.adjacencyMatrix[vertexIndex2][vertexIndex1] = 1; } /** * 深度优先遍历图 */ public void traverseDepth(){ Stack<Vertex> s = new Stack<>(); System.out.print(vertexList.get(0).getLabel()); vertexList.get(0).setVisited(true); int targetIndex = 0; while(true){ int size = getSize(); for(int i = 0; i < size; i++){ if((!vertexList.get(i).isVisited()) && adjacencyMatrix[targetIndex][i] == 1){ Vertex temp = vertexList.get(i); temp.setVisited(true); System.out.print(vertexList.get(i).getLabel()); s.push(vertexList.get(targetIndex)); targetIndex = i; i = 0; } } if(!s.isEmpty()){ Vertex tempV = s.pop(); targetIndex = findVertex(tempV); }else{ break; } } //恢复 int len = vertexList.size(); for(int i = 0; i < len; i++){ vertexList.get(i).setVisited(false); } } /** * 广度优先遍历图 */ public void traverseBroad(){ Queue<Vertex> q = new LinkedList<>(); //第一个访问的是第一个顶点 System.out.print(vertexList.get(0).getLabel()); vertexList.get(0).setVisited(true); //当前所在的节点 int targetIndex = 0; int size = getSize(); while(true){ for(int i = 0; i < size; i++){ //是否已经被访问过以及是否有边的联系 if((!vertexList.get(i).isVisited()) && adjacencyMatrix[targetIndex][i] == 1){ Vertex t = vertexList.get(i); q.add(t); t.setVisited(true); System.out.print(vertexList.get(i).getLabel()); } } if(!q.isEmpty()){ //从队列中弹出顶点 Vertex tempV = q.poll(); //改变当前所在的节点下标 targetIndex = findVertex(tempV); }else{ break; } } //恢复 int len = vertexList.size(); for(int i = 0; i < len; i++){ vertexList.get(i).setVisited(false); } } private int findVertex(Vertex vertex){ for(int i = 0; i < vertexList.size(); i++){ if(vertex == vertexList.get(i)) return i; } return -1; } public int getSize(){ return this.vertexList.size(); } /** * 最小生成树 * 思路:和上面的深度优先遍历图的方法基本相同,只是下面的method是在遍历的同时记录下了边的关系。 */ public void growMinTree(){ int len2 = vertexList.size(); int[][] tempDyadic = new int[len2][len2]; Stack<Vertex> s = new Stack<>(); System.out.print(vertexList.get(0).getLabel()); vertexList.get(0).setVisited(true); int targetIndex = 0; while(true){ int size = getSize(); for(int i = 0; i < size; i++){ if((!vertexList.get(i).isVisited()) && adjacencyMatrix[targetIndex][i] == 1){ //最小生成树的邻接矩阵的关键:标记访问过并且有链接的连线,放在新的二维数组中 tempDyadic[targetIndex][i] = 1; Vertex temp = vertexList.get(i); temp.setVisited(true); System.out.print(vertexList.get(i).getLabel()); s.push(vertexList.get(targetIndex)); targetIndex = i; i = 0; } } if(!s.isEmpty()){ Vertex tempV = s.pop(); targetIndex = findVertex(tempV); }else{ break; } } //恢复为都未访问过 int len = vertexList.size(); for(int i = 0; i < len; i++){ vertexList.get(i).setVisited(false); } //打印邻接矩阵 System.out.println(); System.out.println("最小生成树的邻接矩阵:"); for(int i = 0; i < len; i++){ for(int k = 0; k < len; k++){ System.out.print(tempDyadic[i][k]+" "); } System.out.println(); } //改变矩阵的引用 adjacencyMatrix = tempDyadic; } public void printMatrix(){ System.out.println("图的邻接矩阵: "); int len = vertexList.size(); for(int i = 0; i < len; i++){ for(int k = 0; k < len; k++){ System.out.print(adjacencyMatrix[i][k]+" "); } System.out.println(); } } } /** * 采用连接矩阵的无向图 * @author admin * */ class ConnectionMatrixGraph{ // private LinkedList<Vertex> vertexList; private LinkedList<LinkedList<Vertex>> connectionMatrix; public ConnectionMatrixGraph(){ // vertexList = new ArrayList<>(); connectionMatrix = new LinkedList<>(); } public void addVertex(String label){ LinkedList<Vertex> v = new LinkedList<Vertex>(); v.add(new Vertex(label)); connectionMatrix.add(v); } public void addEdge(int a, int b){ LinkedList<Vertex> vlist1 = this.connectionMatrix.get(a); LinkedList<Vertex> vlist2 = this.connectionMatrix.get(b); vlist1.add(vlist2.get(0)); vlist2.add(vlist1.get(0)); } /** * 打印链接矩阵 */ public void printConnectionMatrix(){ java.util.Iterator<LinkedList<Vertex>> iter = connectionMatrix.iterator(); while(iter.hasNext()){ LinkedList<Vertex> tempLink = iter.next(); java.util.Iterator<Vertex> iter2 = tempLink.iterator(); while(iter2.hasNext()){ Vertex v = iter2.next(); System.out.print(v.getLabel()+"-->"); } System.out.println(); } } /** * 图的广度优先遍历,不需栈 */ public void traverseBroad(){ Iterator<LinkedList<Vertex>> iter = null; iter = connectionMatrix.iterator(); while(iter.hasNext()){ LinkedList<Vertex> tempLink = iter.next(); Iterator<Vertex> iter2 = null; iter2 = tempLink.iterator(); Vertex tempV2 = null; if(iter2.hasNext()){ tempV2 = iter2.next(); //如果没有访问过 if(!tempV2.isVisited()){ tempV2.setVisited(true); System.out.print(tempV2.getLabel()); } }else{ continue; } while(iter2.hasNext()){ Vertex tempV = iter2.next(); if(!tempV.isVisited()){ tempV.setVisited(true); System.out.print(tempV.getLabel()); } } } } } /** * 顶点 * @author admin * */ class Vertex{ private String label; private boolean isVisited; public Vertex(String label){ this.label = label; this.isVisited = false; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public boolean isVisited() { return isVisited; } public void setVisited(boolean isVisited) { this.isVisited = isVisited; } }结果:
![](http://img2.ph.126.net/mdnSyEdfym8WsYfgsU8Lsg==/6630791788282373270.png)
相关文章推荐
- 哈夫曼树--顺序结构(建立、编码、解码)
- 哈夫曼树--链式结构(建立huffman树、编码、解码)
- Jquery动态操作checkbox
- oracle exp 命令导大数据
- 任意2n个整数,从其中选出n个整数,使得选出的n个整数和同剩下的n个整数之和的差最小
- ios开发系列之NSDate,NSDateFormatter,NSDateComponents和NSCalendar
- 压缩文件(zip)--适用于目录下既有目录又有文件的情况
- stripes framework(框架)入门教程(附案例分析)
- spring整合mybatis(入门级简单教程5)--使用mybatis的API
- spring整合mybatis(入门级简单教程4)--扫描mapper类
- spring整合mybatis(入门级简单教程3)--获取sqlSession对象
- spring整合mybatis(入门级简单教程2)
- spring整合mybatis(入门级简单教程1)--在spring中配置c3p0,并成功测试
- IDEA加密文件Base64转换String传输以及报文摘要MD5防止恶意篡改
- 使用struts2框架来实现CRUD(create、read、update、delete)
- MVC、JSP实现mysql的增删改查功能的封装和简陋的界面交互
- java坦克游戏
- 贪吃蛇游戏(java)
- 考研成绩查询系统(jsp、mysql、java)
- 用java实现优先级别队列