最近在温习数据结构与算法,使用Java语言来描述(C两年没写过了?),把 code 发出来大家一起交流学习下。
前言
我这里就直接放出代码了,关于图的知识请自己找资料学习。
我这里参考学习的是 马克·艾伦·维斯 的 《数据结构与算法分析Java语言描述》第三版。(原书作者提供的代码可在这里找到)
我的Java代码可能比较字多、复杂,比如顶点跟图的属性啦、方法啦什么的,这估计是写Java Web时养成的习惯?,别介意。
数据结构与算法的Java实现简介?
顶点:一个类,存有紧邻节点跟权值信息,有极强的扩展/代表性。具体请看我写的代码注释跟方法签名
图:一个类,可以是表示有向或无向、有权或无权图,内置了一堆我自己写的(有用)方法。
图算法:包含了图的相关算法的一个工具类,包含了拓扑排序、无权最短路径、Dijkstra(有权最短路径)、Prim、Kruskal(最小生成树)。
不相交集:因为Kruskal算法使用一个不相交集的话非常简单,因此我自己又写了一个不相交集的类。
其他:你可以看到,我的代码中链表、队列、集合、Map等这些都使用了JDK自带的,这样方便你更专注当前算法的设计。类中使用了泛型、少许Lambda,部分方法重载等。
测试
package mydt.graph;
import java.util.Arrays;
import java.util.List;
public class GraphTest {
public static void main(String[] args) throws Exception {
//得到图实例
//无权有向图 测试无权最短路径算法
Graph<Integer> graph1 = getGraph1();
//一个无权有向图 测试无权最短路径算法
Graph<Integer> graph2 = getGraph2();
//一个带权有向图 测试Dijkstra算法
Graph<Integer> graph3 = getGraph3();
//一个无向带权图 测试Prim与Kruskal算法
Graph<Integer> graph4 = getGraph4();
//测试拓扑排序
System.out.println("无权有向图 测试无权最短路径算法:\n" + graph1);
List<String> list1 = GraphAlg.topsort(graph1);
System.out.println(list1);
System.err.println("\n=== === ===\n");
//测试无权最短路径算法
System.out.println("一个无权有向图 测试无权最短路径算法:\n" + graph1);
GraphAlg.unweightedShortestPath(graph2, "v1");
System.err.println("\n=== === ===\n");
//测试Dijkstra算法
System.out.println("一个带权有向图 测试Dijkstra算法:\n" + graph1);
System.out.println();
GraphAlg.dijkstra(graph3, "v1");
System.err.println("\n=== === ===\n");
//测试Prim与Kruskal算法
System.out.println("一个无向带权图 测试Prim与Kruskal算法:\n" + graph1);
System.out.println();
System.out.println("Prim算法结果");
GraphAlg.prim(graph4);
System.out.println("\nKruskal算法结果");
List<String[]> list = GraphAlg.kruskal(graph4);
list.forEach(n -> System.out.println(Arrays.toString(n)));
}
/**
* 得到一个无圈有向图G
*/
public static Graph<Integer> getGraph1(){
Graph<Integer> graph = new Graph<>();
graph.addVertex("v1", 1, "v3", "v2", "v4");
graph.addVertex("v2", 2, "v4", "v5");
graph.addVertex("v3", 3, "v6");
graph.addVertex("v4", 4, "v3", "v6", "v7");
graph.addVertex("v5", 5, "v4", "v7");
graph.addVertex("v6", 6, new String[]{});
graph.addVertex("v7", 7, "v6");
return graph;
}
/**
* 得到一个无权有向图G
*/
public static Graph<Integer> getGraph2(){
Graph<Integer> graph = new Graph<>();
graph.addVertex("v1", 1, "v2", "v4");
graph.addVertex("v2", 2, "v4", "v5");
graph.addVertex("v3", 3, "v1", "v6");
graph.addVertex("v4", 4, "v3", "v5", "v6", "v7");
graph.addVertex("v5", 5, "v6");
graph.addVertex("v6", 6, new String[]{});
graph.addVertex("v7", 7, "v6");
return graph;
}