图的基本操作
来源:互联网 发布:模考软件pp2 编辑:程序博客网 时间:2024/05/21 15:43
import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.LinkedList;import java.util.List;import java.util.Queue;import java.util.Stack;//邻接矩阵class Graph{ char[] vertexs; int[][] edges; int vertexnum; int edgenum;}class SortedEdge implements Comparable<SortedEdge>{ int m; int n; int weight; @Override public int compareTo(SortedEdge o) { if(this.weight < o.weight) return -1; else if(this.weight > o.weight) return 1; else return 0; }}class UndirectedGraph{ public Graph createGraph(){ Graph graph = new Graph(); int vertexnum = 5; int edgenum = 8; //顶点数 边数 graph.vertexnum = vertexnum; graph.edgenum = edgenum; char[] vertexs = new char[vertexnum]; int[][] edges = new int[vertexnum][vertexnum]; for(int i = 0; i < vertexnum; i++) for(int j = 0; j < vertexnum; j++) edges[i][j] = 0; //顶点 for(int i = 0; i < vertexnum; i++) vertexs[i] = (char) (i + 'A'); graph.vertexs = vertexs; //边 edges[0][1] = 3; edges[0][2] = 5; edges[0][3] = 8; edges[1][0] = 3; edges[1][2] = 6; edges[1][3] = 4; edges[1][4] = 11; edges[2][0] = 5; edges[2][1] = 6; edges[2][3] = 2; edges[3][0] = 8; edges[3][1] = 4; edges[3][2] = 2; edges[3][4] = 10; edges[4][1] = 11; edges[4][3] = 10; graph.edges = edges; return graph; } public void printGraph(Graph graph){ for(int i = 0; i < graph.vertexnum; i++){ System.out.print(graph.vertexs[i] + " "); } System.out.println(); for(int i = 0; i < graph.vertexnum; i++){ for(int j = 0; j < graph.vertexnum; j++) System.out.print(graph.edges[i][j] + " "); System.out.println(); } } public void DFS(Graph graph, int v, int[] visited){ visited[v] = 1; System.out.print(graph.vertexs[v] + " "); for(int j = 0; j < graph.vertexnum; j++) { if (graph.edges[v][j] != 0 && visited[v] == 0) { DFS(graph, v, visited); } } } public void deepFirstSearch(Graph graph){ int[] visited = new int[graph.vertexnum]; Arrays.fill(visited, 0); for(int i = 0; i < graph.vertexnum; i++) if(visited[i] == 0) DFS(graph, i, visited); } public void BFS(Graph graph, int v, int[] visited){ visited[v] = 1; Queue<Integer> queue = new LinkedList<Integer>(); queue.add(v); while(!queue.isEmpty()){ int node = queue.poll(); System.out.print(graph.vertexs[node] + " "); for(int j = 0; j < graph.vertexnum; j++) { if (graph.edges[node][j] != 0 && visited[j] == 0) { queue.add(j); visited[j] = 1; } } } } public void breadthFirstSearch(Graph graph){ int[] visited = new int[graph.vertexnum]; Arrays.fill(visited, 0); for(int i = 0; i < graph.vertexnum; i++) if(visited[i] == 0) BFS(graph, i, visited); } public void sortGraphEdgesByWeights(Graph graph, ArrayList<SortedEdge> sortedEdges){ Collections.sort(sortedEdges); } //求单源最短路径 初始化有向图邻接矩阵 public Graph initDirectedGraph(){ Graph graph = new Graph(); int vertexnum = 6; int edgenum = 11; //顶点数 边数 graph.vertexnum = vertexnum; graph.edgenum = edgenum; char[] vertexs = new char[vertexnum]; int[][] edges = new int[vertexnum][vertexnum]; for(int i = 0; i < vertexnum; i++) for(int j = 0; j < vertexnum; j++) if(i == j) edges[i][j] = 0; else edges[i][j] = 9999; //顶点 for(int i = 0; i < vertexnum; i++) vertexs[i] = (char) (i + 'A'); graph.vertexs = vertexs; //边 edges[0][1] = 50; edges[0][2] = 10; edges[0][4] = 45; edges[1][2] = 15; edges[1][4] = 10; edges[2][0] = 20; edges[2][3] = 15; edges[3][1] = 20; edges[3][4] = 35; edges[4][3] = 30; edges[5][3] = 3; graph.edges = edges; return graph; } //单源最短路径 public void dijkstraShortestPath(Graph graph, int v){ int[] distance = new int[graph.vertexnum]; int[] found = new int[graph.vertexnum]; int[] path = new int[graph.vertexnum + 1]; path[0] = -1; for(int i = 0; i < graph.vertexnum; i++){ found[i] = 0; distance[i] = graph.edges[v][i]; if(i != 0 && i != v && distance[i] != 9999) path[i] = v; else path[i] = -1; } found[v] = 1; distance[v] = 0; for(int i = 0; i < graph.vertexnum - 2; i++){ int u = chooseLowestCostEdge(graph, distance, found); found[u] = 1; for(int w = 0; w < graph.vertexnum; w++) if(found[w] == 0) if(distance[u] + graph.edges[u][w] < distance[w]){ distance[w] = distance[u] + graph.edges[u][w]; path[w] = u; } } printShortestPaths(graph, v, path, distance); } public void printShortestPaths(Graph graph, int v, int[] path, int[] distance){ System.out.println("最短路径信息:"); for(int i = 1; i < graph.vertexnum; i++){ System.out.println(v + " 到 " + i +" 的 最短路径为 :"); int k = i; Stack<Integer> stack = new Stack<Integer>(); if(path[i] != -1) stack.add(i); while(path[k] != -1){ stack.add(path[k]); k = path[k]; } if(stack.isEmpty()) System.out.print("没有从 " + v +" 到 " + i + "的路径!"); while(!stack.isEmpty()){ if(stack.size() > 1) System.out.print(stack.pop() + "->"); else System.out.print(stack.pop()); } System.out.print("\t最小代价 :" + distance[i]); System.out.println(); } } public int chooseLowestCostEdge(Graph graph, int[] distance, int[] found){ int min, minpos; min = Integer.MAX_VALUE; minpos = -1; for(int i = 0; i < graph.vertexnum; i++){ if(distance[i] < min && found[i] == 0){ min = distance[i]; minpos = i; } } return minpos; } //所有顶点对之间的最短路径 public void floydWarshallShortestPath(Graph graph){ int i, j , k; int n = graph.vertexnum; int[][] distance = new int[n][n]; int[][] paths = new int[n][n]; for(i = 0; i < n; i++) for(j = 0; j < n; j++){ distance[i][j] = graph.edges[i][j]; if(distance[i][j] < 9999) paths[i][j] = i; else paths[i][j] = -1; } //最短路径算法 for(k = 0; k < n; k++) for(i = 0; i < n; i++) for(j = 0; j < n; j++) if(distance[i][k] + distance[k][j] < distance[i][j]){ // System.out.println("distance["+i+"]["+k+"] = " + distance[i][k]+" , distance["+k+"]["+j+"] ="+ distance[k][j]+" , distance["+i+"]["+j+"] = " + distance[i][j]); // System.out.println("distance["+i+"]["+k+"] + distance["+k+"]["+j+"] < distance["+i+"]["+j+"]"); distance[i][j] = distance[i][k] + distance[k][j]; // System.out.println("distance["+i+"]["+j+"] = " + distance[i][j]); paths[i][j] = paths[k][j]; } printAllShortestPathsWithWeight(graph, distance, paths); } public void printAllShortestPathsWithWeight(Graph graph, int[][] distance, int[][] paths){ Stack<Integer> stack = new Stack<Integer>(); int n = graph.vertexnum; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) if(i != j && distance[i][j] < 9999){ stack.add(j); int v = paths[i][j]; while(v != i && v != j){ stack.add(v); v = paths[i][v]; } System.out.print(i + " -> "); while(!stack.isEmpty()){ if(stack.size() > 1) System.out.print(stack.pop() + " -> "); else System.out.print(stack.pop()); } System.out.println(" 长度为 :" + distance[i][j]); }else if(i != j && distance[i][j] == 9999){ System.out.println("没有从 " + i +" 到 " + j + "的路径!"); } } //最小代价生成树 Kruskal 算法 和Prim 算法 public Graph initUndirectedGraph(){ Graph graph = new Graph(); int vertexnum = 7; int edgenum = 9; //顶点数 边数 graph.vertexnum = vertexnum; graph.edgenum = edgenum; char[] vertexs = new char[vertexnum]; int[][] edges = new int[vertexnum][vertexnum]; int n = vertexnum; for(int i = 0; i < vertexnum; i++) for(int j = 0; j < vertexnum; j++) if(i == j) edges[i][j] = 0; else edges[i][j] = 9999; //顶点 for(int i = 0; i < vertexnum; i++) vertexs[i] = (char) (i + 'A'); graph.vertexs = vertexs; //边 edges[0][1] = 28; edges[0][5] = 10; edges[1][2] = 16; edges[1][6] = 14; edges[2][3] = 12; edges[3][4] = 22; edges[3][6] = 18; edges[4][6] = 24; edges[4][5] = 25; edges[1][0] = 28; edges[5][0] = 10; edges[2][1] = 16; edges[6][1] = 14; edges[3][2] = 12; edges[4][3] = 22; edges[6][3] = 18; edges[6][4] = 24; edges[5][4] = 25; graph.edges = edges; return graph; } //kuskal最小生成树算法 public void kruskalMinimunCostSpanningTree(Graph graph){ int n = graph.vertexnum; int lowestCost = 0; List<SortedEdge> selectedEdges = new ArrayList<SortedEdge>(); List<SortedEdge> edges = new ArrayList<SortedEdge>(); int[] father = new int[n]; for(int p = 0; p < n; p++) father[p] = p; //无向图只选取上三角形的边 for(int i = 0; i < n; i++) for(int j = i + 1; j < n; j++) if(i != j){ SortedEdge edge = new SortedEdge(); edge.m = i; edge.n = j; edge.weight = graph.edges[i][j]; edges.add(edge); } Collections.sort(edges); while(selectedEdges.size() < n - 1 && !edges.isEmpty()){ SortedEdge minEdge = edges.get(0); edges.remove(0); int k, g; /*for(k = minEdge.m; k != x[k]; k = x[k]); for(g = minEdge.n; g != x[g]; g = x[g]);*/ k = find_set(minEdge.m, father); g = find_set(minEdge.n, father); //边的两个端点位于不同集合,构不成环,选中该边 if(k != g){ father[g] = k; selectedEdges.add(minEdge); lowestCost += minEdge.weight; } } if(selectedEdges.size() < n - 1){ System.out.println("改图没有最小代价生成树 !"); return; } //选中的边以及最小代价 System.out.println("Kruskal最小代价生成树-选中的边以及权值为:"); for(SortedEdge se : selectedEdges) System.out.println(se.m + " - " + se.n + " - " + se.weight); System.out.println("最小代价为 :" + lowestCost); } public int find_set(int x,int[] father){ if(x != father[x]) father[x] = find_set(father[x], father); return father[x]; } //Prim最小生成树算法 public void primMinimunCostSpanningTree(Graph graph){ int n = graph.vertexnum; int lowestCost = 0; List<SortedEdge> selectedEdges = new ArrayList<SortedEdge>(); List<SortedEdge> edges = new ArrayList<SortedEdge>(); int[] father = new int[n]; for(int p = 0; p < n; p++) father[p] = p; //无向图只选取上三角形的边 for(int i = 0; i < n; i++) for(int j = i + 1; j < n; j++) if(i != j){ SortedEdge edge = new SortedEdge(); edge.m = i; edge.n = j; edge.weight = graph.edges[i][j]; edges.add(edge); } Collections.sort(edges); int k, g; //先把第一条边加进去 SortedEdge minEdge0 = edges.get(0); edges.remove(0); father[minEdge0.n] = minEdge0.m; selectedEdges.add(minEdge0); int baseSet = minEdge0.m; int i = 0; while(selectedEdges.size() < n - 1 && !edges.isEmpty()){ SortedEdge minEdge = edges.get(i); k = find_set(minEdge.m, father); g = find_set(minEdge.n, father); if((k == baseSet && g != baseSet) || (g == baseSet && k != baseSet)){ edges.remove(i); selectedEdges.add(minEdge); lowestCost += minEdge.weight; if(k == baseSet) father[g] = k; else father[k] = g; i = 0; }else i++; } System.out.println("selectedEdges size:" + selectedEdges.size()); if(selectedEdges.size() < n - 1){ System.out.println("改图没有最小代价生成树 !"); return; } //选中的边以及最小代价 System.out.println("Prim最小代价生成树-选中的边以及权值为:"); for(SortedEdge se : selectedEdges) System.out.println(se.m + " - " + se.n + " - " + se.weight); System.out.println("最小代价为 :" + lowestCost); }}//邻接表class EdgeNode{ int adjvertex; EdgeNode next;}class VertexNode{ char data; EdgeNode firstEdge;}class DGraph{ VertexNode[] adjList; int vertexnum; int edgenum;}class DirectedDGraph{ public int getposition(char[] vexs, char c){ return String.valueOf(vexs).indexOf(c); } public void printVertexEdgeNode(DGraph graph){ for(int i = 0; i < graph.vertexnum; i++){ System.out.println(graph.adjList[i].data + "顶点的所有连接点如下:"); for(EdgeNode p = graph.adjList[i].firstEdge; p != null; p = p.next) System.out.print(p.adjvertex + " "); System.out.println(); } } public DGraph createGraph(){ DGraph graph = new DGraph(); char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'}; char edges[][] = {{'A', 'B'}, {'B', 'C'}, {'B', 'E'}, {'B', 'F'}, {'C', 'E'}, {'D', 'C'}, {'E', 'B'}, {'E', 'D'},{'F', 'G'}}; graph.vertexnum = vexs.length; graph.edgenum = edges.length; graph.adjList = new VertexNode[graph.vertexnum]; //初始化邻接表的顶点 for(int i = 0; i < vexs.length; i++){ graph.adjList[i] = new VertexNode(); graph.adjList[i].data = vexs[i]; graph.adjList[i].firstEdge = null; } //初始化邻接表的边 for(int i = 0; i < edges.length; i++){ EdgeNode edgeNode = new EdgeNode(); int pos1 = getposition(vexs, edges[i][0]); int pos2 = getposition(vexs, edges[i][1]); edgeNode.adjvertex = pos2; edgeNode.next = graph.adjList[pos1].firstEdge; graph.adjList[pos1].firstEdge = edgeNode; } return graph; } public void DFS(DGraph graph, int v, int[] visited){ visited[v] = 1; // System.out.print(v + " "); System.out.print(graph.adjList[v].data + " "); for(EdgeNode edge = graph.adjList[v].firstEdge; edge != null; edge = edge.next) if(visited[edge.adjvertex] == 0) DFS(graph, edge.adjvertex, visited); } public void deepFirstSearch(DGraph graph){ int[] visited = new int[graph.vertexnum]; Arrays.fill(visited, 0); for(int i = 0; i < graph.vertexnum; i++) if(visited[i] == 0) DFS(graph, i, visited); } public void BFS(DGraph graph, int v, int[] visited){ visited[v] = 1; Queue<Integer> queue = new LinkedList<Integer>(); queue.add(v); while(!queue.isEmpty()){ int node = queue.poll(); System.out.print(graph.adjList[node].data + " "); for(EdgeNode edge = graph.adjList[node].firstEdge; edge != null; edge = edge.next) if(visited[edge.adjvertex] == 0){ queue.add(edge.adjvertex); visited[edge.adjvertex] = 1; } } } public void breadthFirstSearch(DGraph graph){ int[] visited = new int[graph.vertexnum]; Arrays.fill(visited, 0); for(int i = 0; i < graph.vertexnum; i++) if(visited[i] == 0) BFS(graph, i, visited); }}public class Tu { public static void main(String[] args) { //邻接矩阵 UndirectedGraph ugraph1 = new UndirectedGraph(); Graph graph1 = ugraph1.createGraph(); System.out.println("Graph DFS:"); ugraph1.deepFirstSearch(graph1); System.out.println("\nGraph BFS:"); ugraph1.breadthFirstSearch(graph1); // graph1.printGraph(graph1.createGraph()); //邻接表 DirectedDGraph dgraph = new DirectedDGraph(); // dgraph.printVertexEdgeNode(dgraph.createGraph()); DGraph graph = dgraph.createGraph(); System.out.println("\nDGraph DFS:"); dgraph.deepFirstSearch(graph); System.out.println("\nDGraph BFS:"); dgraph.breadthFirstSearch(graph); //有向图 //单源最短路径 System.out.println("\n单源最短路径 : "); Graph dgraph3 = ugraph1.initDirectedGraph(); ugraph1.dijkstraShortestPath(dgraph3, 0); //任意两点最短路径 System.out.println("\n所有顶点之间的最短路径 及其长度信息: "); ugraph1.floydWarshallShortestPath(dgraph3); //最小代价生成树 Graph graph4 = ugraph1.initUndirectedGraph(); System.out.println("\n kruskal最小代价生成树:"); ugraph1.kruskalMinimunCostSpanningTree(graph4); System.out.println("\n prim最小代价生成树:"); ugraph1.primMinimunCostSpanningTree(graph4); }}
0 0
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- *图的基本操作*
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图的基本操作
- 图基本操作的实现
- 【数据结构】图的基本操作
- 图的基本、常见操作
- 图的基本操作【严蔚敏】
- 实验 图的基本操作
- 四 图的基本操作
- oracle11g服务端的安装与使用
- cocoStudio: Button三种状态切换
- Android中SQLite数据库的简单使用
- git 简单使用(二)
- avl树左旋右旋的理解
- 图的基本操作
- 微信二次开发前言
- 身份证校验
- bzoj 2186 [Sdoi2008]沙拉公主的困惑 欧拉函数
- C语言----文件读取
- Swift实战训练百度在线音乐案例
- python安装,以及matplotlib及相关组件安装。
- oracle 10g 客户端的一些用法
- 项目中jquery与easyui冲突的解决方法