test 2 Dijkstra
核心代码
主要是利用了个优先队列简化了一些,目的就只是实现功能,不考虑空间,时间了。
package Experiment8;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
public class test2 {
public static void main(String[] args) {
//-------------------------Dijkstra算法
Graph graph = new Graph(); //构建图
//创建各个节点
Vertex a = new Vertex("A");graph.addVertex(a);
Vertex b = new Vertex("B");graph.addVertex(b);
Vertex c = new Vertex("C");graph.addVertex(c);
Vertex d = new Vertex("D");graph.addVertex(d);
Vertex e = new Vertex("E");graph.addVertex(e);
Vertex f = new Vertex("F");graph.addVertex(f);
//创建节点联系
a.addOut(d,30);a.addOut(c,5);a.addIn(b,2);
b.addIn(c,15);b.addOut(a,2);b.addOut(e,8);
c.addIn(a,5);c.addOut(b,15);c.addOut(f,7);
d.addIn(a,30);d.addIn(e,4);d.addIn(f,10);
e.addIn(b,8);e.addIn(f,18);e.addOut(d,4);
f.addIn(c,7);f.addOut(e,18);f.addOut(d,10);
//给每个顶点距离初始化为无穷大
for(Vertex v: graph.vertexLinkedList){
v.dis = Integer.MAX_VALUE;
v.known = false;
}
Queue<Vertex> que = new PriorityQueue<>((v1,v2)->(v1.dis-v2.dis)); //lambda表达式
//采用优先队列对加入的点进行升序排序,队头即为距离最小的顶点
a.dis = 0;
for(Vertex v1: graph.vertexLinkedList)
que.add(v1); //将所有顶点加入至优先队列
while(!que.isEmpty()){ //注意,这边为空就表明全部都访问过了,有些省略不易理解
Vertex tmp = que.poll(); //弹出最小的
tmp.known = true; //标记为已经访问过
for(Edge e1:tmp.out){
if(!e1.v1.known&&tmp.dis+e1.weight<e1.v1.dis){
e1.v1.dis = tmp.dis+e1.weight;
que.remove(e1.v1); //采用优先队列的方式值改变后应当重新出队再入队,才能更新顺序
que.add(e1.v1);
e1.v1.path = tmp;
}
}
}
for(Vertex v:graph.vertexLinkedList){
System.out.print("Destination: "+v.val+" ");
graph.printPath(v);
System.out.println();
}
}
}
顶点类:
package Experiment8;
import java.util.LinkedList;
class Vertex{ //顶点
String val; //数值
LinkedList<Edge> out = new LinkedList<>(); //出度
LinkedList<Edge> in = new LinkedList<>(); //入度
int dis;
boolean known;
Vertex path;
public Vertex(){}
public Vertex(String val){
this.val = val;
}
public void addIn(Vertex v){
Edge e = new Edge(v);
in.add(e);
}
public void addOut(Vertex v){
Edge e = new Edge(v);
out.add(e);
}
public void addIn(Vertex v,int w){
Edge e = new Edge(w,v);
in.add(e);
}
public void addOut(Vertex v,int w){
Edge e = new Edge(w,v);
out.add(e);
}
}
边类:
package Experiment8;
class Edge{
int weight;
Vertex v1;
Edge(){}
Edge(int w,Vertex v1){
this.weight = w;
this.v1 = v1;
}
Edge(Vertex v1){
this.v1 = v1;
}
}
图类:
package Experiment8;
import java.util.LinkedList;
class Graph{
Graph(){
vertexLinkedList = new LinkedList<>();
}
LinkedList<Vertex> vertexLinkedList; //顶点集
public void addVertex(Vertex v){ //加入顶点
vertexLinkedList.add(v);
}
public void clear(){
vertexLinkedList.clear();
}
public boolean AllVisited(){
return vertexLinkedList.size()==checkVisited();
}
int checkVisited(){
int cnt = 0;
for (Vertex v:vertexLinkedList){
if (v.known==true) cnt++;
}
return cnt;
}
public void printPath(Vertex v){
if(v.path!=null){
printPath(v.path);
System.out.print("->");
}
System.out.print(v.val+"(dis:"+v.dis+")");
}
}
test3 和 test2 代码上基本一样,就改动了 dis 的计算
核心代码
package Experiment8;
import java.util.PriorityQueue;
import java.util.Queue;
public class test3 {
public static void main(String[] args) {
//-------------------------Prime算法
Graph graph = new Graph(); //构建图
//创建各个节点
Vertex a = new Vertex("A");graph.addVertex(a);
Vertex b = new Vertex("B");graph.addVertex(b);
Vertex c = new Vertex("C");graph.addVertex(c);
Vertex d = new Vertex("D");graph.addVertex(d);
Vertex e = new Vertex("E");graph.addVertex(e);
Vertex f = new Vertex("F");graph.addVertex(f);
//创建节点联系
a.addIn(d,30);a.addIn(c,5);a.addIn(b,2);
b.addIn(c,15);b.addIn(a,2);b.addIn(e,8);
c.addIn(a,5);c.addIn(b,15);c.addIn(f,7);
d.addIn(a,30);d.addIn(e,4);d.addIn(f,10);
e.addIn(b,8);e.addIn(f,18);e.addIn(d,4);
f.addIn(c,7);f.addIn(e,18);f.addIn(d,10);
//给每个顶点距离初始化为无穷大
for(Vertex v: graph.vertexLinkedList){
v.dis = Integer.MAX_VALUE;
v.known = false;
}
Queue<Vertex> que = new PriorityQueue<>((v1,v2)->(v1.dis-v2.dis)); //lambda表达式
//采用优先队列对加入的点进行升序排序,队头即为距离最小的顶点
a.dis = 0;
for(Vertex v1: graph.vertexLinkedList)
que.add(v1); //将所有顶点加入至优先队列
while(!que.isEmpty()){ //注意,这边为空就表明全部都访问过了,有些省略不易理解
Vertex tmp = que.poll(); //弹出最小的
tmp.known = true; //标记为已经访问过
for(Edge e1:tmp.in){
if(!e1.v1.known&&e1.weight<e1.v1.dis){ //就在这个范围内改了下
e1.v1.dis = e1.weight;
que.remove(e1.v1); //采用优先队列的方式值改变后应当重新出队再入队,才能更新顺序
que.add(e1.v1);
e1.v1.path = tmp;
}
}
}
//输出最小生成树
}
}
test 4
核心代码:
package Experiment8;
import java.util.*;
public class test4 {
public static void main(String[] args) {
//-------------------------Kruskal算法
Graph graph = new Graph(); //构建图
//创建各个节点
Vertex a = new Vertex("A");graph.addVertex(a);
Vertex b = new Vertex("B");graph.addVertex(b);
Vertex c = new Vertex("C");graph.addVertex(c);
Vertex d = new Vertex("D");graph.addVertex(d);
Vertex e = new Vertex("E");graph.addVertex(e);
Vertex f = new Vertex("F");graph.addVertex(f);
//创建节点联系(无向边)
Edge tmp = new Edge(2,a,b);graph.addEdge(tmp);
tmp = new Edge(30,a,d);graph.addEdge(tmp);
tmp = new Edge(5,a,c);graph.addEdge(tmp);
tmp = new Edge(15,b,c);graph.addEdge(tmp);
tmp = new Edge(8,b,e);graph.addEdge(tmp);
tmp = new Edge(7,c,f);graph.addEdge(tmp);
tmp = new Edge(4,e,d);graph.addEdge(tmp);
tmp = new Edge(10,f,d);graph.addEdge(tmp);
tmp = new Edge(18,f,e);graph.addEdge(tmp);
Queue<Edge> que = new PriorityQueue<>((v1, v2)->(v1.weight-v2.weight)); //lambda表达式
//采用优先队列对加入的边进行升序排序,队头即为权重最小的边
for(Edge e1: graph.edgeArrayList){
que.add(e1);
}
DisjSets sets = new DisjSets(graph);
List<Edge> mst = new ArrayList<>();
while (mst.size()!=graph.vertexLinkedList.size()-1){
Edge e2 = que.poll();
Set<Vertex> s1 = sets.find(e2.v1);
Set<Vertex> s2 = sets.find(e2.v2);
if(s1!=s2){
mst.add(e2);
sets.union(s1,s2);
}
}
for(Edge e2:mst){
System.out.println(e2.v1.val+"--"+e2.v2.val);
}
}
}
class DisjSets{
int size;
ArrayList<Set<Vertex>> sets;
Set<Vertex> set;
DisjSets(Graph graph){
sets = new ArrayList<>();
for(Vertex v: graph.vertexLinkedList){ //将全部的顶点作为一个集合初始化
set = new HashSet<>();
set.add(v);
sets.add(set);
}
}
void union(Set<Vertex> s1,Set<Vertex> s2){
s2.addAll(s1);
sets.remove(s1);
}
Set<Vertex> find(Vertex v){
for(Set<Vertex> s:sets){
if(s.contains(v)) return s;
}
return null;
}
}
在边类里也更新了下
package Experiment8;
class Edge{
int weight;
Vertex v1;
Vertex v2;
Edge(){}
Edge(int w,Vertex v1){
this.weight = w;
this.v1 = v1;
}
Edge(Vertex v1){
this.v1 = v1;
}
Edge(int w,Vertex v1,Vertex v2){
this.weight = w;
this.v1 = v1;
this.v2 = v2;
}
}
test 5 和test 6是在图类中添加了dfs 和 bfs
核心代码:
图类
package Experiment8;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
class Graph{
Graph(){
vertexLinkedList = new LinkedList<>();
edgeArrayList = new ArrayList<>();
}
LinkedList<Vertex> vertexLinkedList; //顶点集
ArrayList<Edge> edgeArrayList; //无向边的边集合
public void addVertex(Vertex v){ //加入顶点
vertexLinkedList.add(v);
}
public void clear(){
vertexLinkedList.clear();
}
public boolean AllVisited(){
return vertexLinkedList.size()==checkVisited();
}
int checkVisited(){
int cnt = 0;
for (Vertex v:vertexLinkedList){
if (v.known==true) cnt++;
}
return cnt;
}
public void printPath(Vertex v){
if(v.path!=null){
printPath(v.path);
System.out.print("->");
}
System.out.print(v.val+"(dis:"+v.dis+")");
}
public void addEdge(Edge e){edgeArrayList.add(e);}
void dfs(Vertex v){
v.known = true;
System.out.print(v.val+"->");
for(Edge e1:v.in){
if(!e1.v1.known)
dfs(e1.v1);
}
}
Queue<Vertex> que = new LinkedList<>();
void bfs(Vertex v){
que.add(v);
v.known = true;
while (!que.isEmpty()) {
int cnt = 0;
Vertex tmp = que.poll();
for (Edge e1 : tmp.in) {
if (!e1.v1.known) {
System.out.println(tmp.val + "->" +e1.v1.val);
e1.v1.known = true;
que.add(e1.v1);
cnt++;
}
}
if(cnt>0) System.out.println("-------start:"+tmp.val+"---------");
}
}
}
test5 主程序
package Experiment8;
public class test5 {
public static void main(String[] args) {
//-------------------------dfs算法
Graph graph = new Graph(); //构建图
//创建各个节点
Vertex a = new Vertex("A");graph.addVertex(a);
Vertex b = new Vertex("B");graph.addVertex(b);
Vertex c = new Vertex("C");graph.addVertex(c);
Vertex d = new Vertex("D");graph.addVertex(d);
Vertex e = new Vertex("E");graph.addVertex(e);
Vertex f = new Vertex("F");graph.addVertex(f);
//创建节点联系(无向边)
a.addIn(b,2);a.addIn(d,30);a.addIn(c,5);
b.addIn(e,8);b.addIn(c,15);b.addIn(a,2);
c.addIn(f,7);c.addIn(b,15);c.addIn(a,5);
d.addIn(e,4);d.addIn(a,30);d.addIn(f,10);
e.addIn(b,8);e.addIn(d,4);e.addIn(f,18);
f.addIn(e,18);f.addIn(c,7);f.addIn(d,10);
graph.dfs(a);
}
}
test 6 主程序
package Experiment8;
public class test6 {
public static void main(String[] args) {
//-------------------------dfs算法
Graph graph = new Graph(); //构建图
//创建各个节点
Vertex a = new Vertex("A");graph.addVertex(a);
Vertex b = new Vertex("B");graph.addVertex(b);
Vertex c = new Vertex("C");graph.addVertex(c);
Vertex d = new Vertex("D");graph.addVertex(d);
Vertex e = new Vertex("E");graph.addVertex(e);
Vertex f = new Vertex("F");graph.addVertex(f);
//创建节点联系(无向边)
a.addIn(b,2);a.addIn(d,30);a.addIn(c,5);
b.addIn(e,8);b.addIn(c,15);b.addIn(a,2);
c.addIn(f,7);c.addIn(b,15);c.addIn(a,5);
d.addIn(e,4);d.addIn(a,30);d.addIn(f,10);
e.addIn(b,8);e.addIn(d,4);e.addIn(f,18);
f.addIn(e,18);f.addIn(c,7);f.addIn(d,10);
graph.bfs(a);
}
}