图的邻接矩阵表示:
package com.AlgorithmDemo.Graphic; /* * author:Tammy Pi * function:邻接矩阵的图 */ public class AdMatrixGraph { //节点个数 private int nodenum=0; //边个数 private int cirnum=0; //邻接矩阵 private int[][] matrix; //构造函数,初始化图 public AdMatrixGraph(int nodenum,int cirnum) { this.nodenum=nodenum; this.cirnum=cirnum; matrix=new int[nodenum][nodenum]; for(int i=0;i<nodenum;i++) { for(int j=0;j<nodenum;j++) { matrix[i][j]=0; } } } public int getNodenum() { return nodenum; } public void setNodenum(int nodenum) { this.nodenum = nodenum; } public int getCirnum() { return cirnum; } public void setCirnum(int cirnum) { this.cirnum = cirnum; } public int[][] getMatrix() { return matrix; } public void setMatrix(int[][] matrix) { this.matrix = matrix; } //无向图 public void add(int i,int j) { this.matrix[i][j]=1; this.matrix[j][i]=1; } //无向图重载 public void add(int i,int j,int data) { this.matrix[i][j]=data; this.matrix[j][i]=data; } }
算法中需用到的队列:
package com.AlgorithmDemo.Container; import java.util.*; /* * author:Tammy Pi * function:队列容器 */ public class MyQueue { private List<Integer> queue; public MyQueue() { queue=new LinkedList<Integer>(); } public void addElement(int elem) { queue.add(elem); } public boolean isEmtpy() { if(queue==null||queue.size()==0) { return true; } return false; } public int removeElement() { return queue.remove(0); } public int getSize() { if(queue!=null) { return queue.size(); } return 0; } //清空队列 public void clear() { queue.clear(); } //用于测试的主函数 public static void main(String[] args) { int[] a=new int[]{2,3,1,5}; MyQueue queue=new MyQueue(); for(int i=0;i<a.length;i++) { queue.addElement(a[i]); } for(int i=0;i<a.length;i++) { System.out.print(queue.removeElement()+" "); } System.out.println("queue:"+queue.getSize()); } }
BFS和DFS算法:
package com.AlgorithmDemo.Graphic; import java.util.*; import com.AlgorithmDemo.Container.MyQueue; /* * author:Tammy Pi * function:图的邻接矩阵表示,即DFS和BFS */ public class BFSVSDFS { private AdMatrixGraph graph; private int[] visited=null; private MyQueue queue=null; public BFSVSDFS(AdMatrixGraph graph) { this.graph=new AdMatrixGraph(graph.getNodenum(),graph.getCirnum()); visited=new int[this.graph.getNodenum()]; queue=new MyQueue(); this.graph.add(0,1); this.graph.add(0,2); this.graph.add(0,3); this.graph.add(1,5); this.graph.add(5,4); this.graph.add(2,6); this.graph.add(3,7); } //DFS public void DFSTraverse(int i) { queue.addElement(i); while(!queue.isEmtpy()) { int node=queue.removeElement(); visited[i]=1; System.out.print(i+" "); for(int j=0;j<graph.getNodenum();j++) { if(graph.getMatrix()[node][j]==1&&visited[j]==0) { DFSTraverse(j); } } } }//DFSTraverse public void DFS() { //初始化,设置所有节点均未访问过 for(int i=0;i<graph.getNodenum();i++) { visited[i]=0; } queue.clear(); //开始遍历 for(int i=0;i<graph.getNodenum();i++) { if(visited[i]==0) { DFSTraverse(i); } } }//DFS //BFS public Integer getNearNode(int i) { for(int j=0;j<this.graph.getNodenum();j++) { if(this.graph.getMatrix()[j][i]==1&&visited[j]==0) { return j; } } return null; } public void BFS() { //初始化,设置node未访问 for(int i=0;i<this.graph.getNodenum();i++) { visited[i]=0; } queue.clear(); //广度遍历 queue.addElement(0); System.out.print("0 "); visited[0]=1; while(!queue.isEmtpy()) { int node=queue.removeElement(); //遍历它的所有节点 for(Integer j=getNearNode(node);j!=null;j=getNearNode(node)) { System.out.print(j+" "); visited[j]=1; queue.addElement(j); } } } //用于测试的主函数 public static void main(String[] args) { AdMatrixGraph graph=new AdMatrixGraph(8,7); BFSVSDFS bfs=new BFSVSDFS(graph); System.out.print("深度遍历的结果为:"); bfs.DFS(); System.out.println(); System.out.print("广度遍历的结果为:"); bfs.BFS(); } }
最小生成树Prim算法:
package com.AlgorithmDemo.MinimumSpaninngTree; import com.AlgorithmDemo.Graphic.AdMatrixGraph; /* * author:Tammy Pi * function:最小生成树算法 */ public class PrimAlgorithm { private AdMatrixGraph graph; private int[] s=null; private int index=-1; public void createTree(int nodenum,int cirnum) { graph=new AdMatrixGraph(nodenum,cirnum); s=new int[graph.getNodenum()]; this.graph.add(0,1,1); this.graph.add(0,3,1); this.graph.add(0,2,3); this.graph.add(3,2,1); } public boolean isContain(int j) { for(int k=0;k<=index;k++) { if(s[k]==j) { return true; } } return false; } public int getMinValue(int node) { int minValue=Integer.MAX_VALUE; for(int i=0;i<=index;i++) { if(this.graph.getMatrix()[i][node]!=0&&this.graph.getMatrix()[i][node]<minValue) { minValue=this.graph.getMatrix()[i][node]; } } return minValue; } public void prim() { //首先将0节点加入集合S中 s[++index]=0; System.out.print("用Prim算法得到的最小生成树为:"+0+" "); while(!(index==graph.getNodenum()-1)) { int minIndex=0; int minValue=Integer.MAX_VALUE; //计算与集合s中的点距离最小的点 for(int j=0;j<graph.getNodenum();j++) { if(!isContain(j)) { if(getMinValue(j)<minValue) { minIndex=j; minValue=getMinValue(j); } } } System.out.print(minIndex+" "); s[++index]=minIndex; } System.out.println(); } //用于测试的主函数 public static void main(String[] args) { PrimAlgorithm prim=new PrimAlgorithm(); prim.createTree(4,4); prim.prim(); } }
最小生成树Kruscal算法:
package com.AlgorithmDemo.MinimumSpaninngTree; import com.AlgorithmDemo.Graphic.AdMatrixGraph; /* * author:Tammy Pi * function:用Kruscal算法得到最小生成树 */ public class KruscalAlgorithm { private AdMatrixGraph graph; private int[] s=null; private int index=-1; private int index1=-1; public void createTree(int nodenum,int cirnum) { graph=new AdMatrixGraph(nodenum,cirnum); s=new int[graph.getNodenum()]; this.graph.add(0,1,1); this.graph.add(0,3,1); this.graph.add(0,2,3); this.graph.add(3,2,1); } //在S集合中包含 public boolean isContain(int j) { for(int k=0;k<=index;k++) { if(s[k]==j) { return true; } } return false; } //找到最短边的两端节点序号 public int[] getMinCir() { int[] minIndex=new int[2]; int minValue=Integer.MAX_VALUE; for(int j=0;j<this.graph.getNodenum();j++) { for(int k=0;k<this.graph.getNodenum();k++) { //j和k不能相同 if(j==k) { continue; } //最小生成树不能包括环 if(isContain(j)&&isContain(k)) { continue; } if(this.graph.getMatrix()[j][k]!=0&&this.graph.getMatrix()[j][k]<minValue) { minValue=this.graph.getMatrix()[j][k]; index1=-1; if(!isContain(j)) { minIndex[++index1]=j; } if(!isContain(k)) { minIndex[++index1]=k; } } }//for k }//for j return minIndex; } public void kruscal() { System.out.print("Kruscal算法得到的最小生成树为:"); while(!(index==this.graph.getNodenum()-1)) { int[] minIndex=getMinCir(); for(int i=0;i<=index1;i++) { s[++index]=minIndex[i]; System.out.print(minIndex[i]+" "); } } System.out.println(); } //用于测试的主函数 public static void main(String[] args) { KruscalAlgorithm kruscal=new KruscalAlgorithm(); kruscal.createTree(4,4); kruscal.kruscal(); } }
单源最短路径算法:
package com.AlgorithmDemo.sigleSource.shortestPath; import com.AlgorithmDemo.Graphic.AdMatrixGraph; import java.util.*; /* * author:Tammy Pi * function:单源最短路径Dijkstra */ public class DijkstraAlgorithm { private AdMatrixGraph graph; //用于存放S集合 private int[] s=null; //当前节点 private int currentNode=0; //目的节点 private int targetNode=0; //用于记录 private int[] pre; //用于记录各个节点与当前节点的距离 private int[] record; private int index=-1; private int index1=-1; public void createTree(int nodenum,int cirnum) { graph=new AdMatrixGraph(nodenum,cirnum); s=new int[graph.getNodenum()]; pre=new int[graph.getNodenum()]; record=new int[graph.getNodenum()]; int[][] kk=new int[this.graph.getNodenum()][this.graph.getNodenum()]; for(int i=0;i<kk.length;i++) { for(int j=0;j<kk.length;j++) { kk[i][j]=Integer.MAX_VALUE; } } this.graph.setMatrix(kk); this.graph.add(0,1,4); this.graph.add(0,4,1); this.graph.add(0,3,5); this.graph.add(4,1,1); this.graph.add(1,2,1); this.graph.add(2,3,1); //源节点为0,目标节点为2 this.currentNode=0; this.targetNode=2; s[++index]=0; for(int i=0;i<this.graph.getNodenum();i++) { pre[i]=-1; } for(int i=0;i<this.graph.getNodenum();i++) { record[i]=Integer.MAX_VALUE; } record[0]=0; } public boolean isContain(int j) { for(int i=0;i<=index;i++) { if(s[i]==j) { return true; } } return false; } //找到最近的点 public int getNearest() { int minIndex=-1; int minValue=Integer.MAX_VALUE; for(int i=0;i<this.graph.getNodenum();i++) { if(isContain(i)) { continue; } if(record[i]<minValue) { minValue=record[i]; minIndex=i; } } return minIndex; } //Dijkstra算法 public void dijkstra() { while(!(index==this.graph.getNodenum()-1)) { for(int i=0;i<this.graph.getNodenum();i++) { if(i!=currentNode&&!isContain(i)&&this.graph.getMatrix()[currentNode][i]!=Integer.MAX_VALUE) { if(record[currentNode]+this.graph.getMatrix()[currentNode][i]<record[i]) { record[i]=record[currentNode]+this.graph.getMatrix()[currentNode][i]; pre[i]=currentNode; } }//if i }//for i currentNode=getNearest(); s[++index]=currentNode; }//while s //输出 System.out.println("Dijkstra算法求得单源最短路径:"); for(int i=1;i<this.graph.getNodenum();i++) { System.out.println(i+"距离0最短距离:"+record[i]+",它的前驱为:"+pre[i]); } System.out.println(); } public static void main(String[] args) { DijkstraAlgorithm dijkstra=new DijkstraAlgorithm(); dijkstra.createTree(5,6); dijkstra.dijkstra(); } }