package sy10;
public class GenerateGraph {
public final static int INFINITY = Integer.MAX_VALUE;
public static MGraph generateMGraph() {
Object vexs[] = { "学校正门", "学校东门", "学校西门", "学校北门", "食堂", "磁悬浮列车实验室" , "樱花大道", "图书馆", "体育场", "体育馆", "游泳馆", "礼堂", "教学楼", "宿舍"};
int[][] arcs = {
{INFINITY, INFINITY, INFINITY, INFINITY, 35, INFINITY ,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,5,INFINITY,INFINITY},
{INFINITY,INFINITY, INFINITY, INFINITY, INFINITY, INFINITY ,INFINITY,INFINITY,INFINITY,INFINITY,75,INFINITY,INFINITY,10},
{INFINITY,INFINITY,INFINITY,INFINITY,30,INFINITY,INFINITY,5,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY },
{INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,15,50,INFINITY,15,20,INFINITY,INFINITY,INFINITY},
{35, INFINITY, 30, INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,60,INFINITY,INFINITY,40,INFINITY,INFINITY },
{ INFINITY, INFINITY, INFINITY, INFINITY, INFINITY, INFINITY,INFINITY,INFINITY,45,INFINITY,INFINITY,10,INFINITY,INFINITY } ,
{INFINITY,INFINITY,INFINITY,15,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY},
{INFINITY,INFINITY,5,50,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY},
{INFINITY,INFINITY,INFINITY,INFINITY,60,45,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,50,INFINITY,INFINITY},
{INFINITY,INFINITY,INFINITY,15,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,20,INFINITY,INFINITY,100},
{INFINITY,75,INFINITY,20,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,20,INFINITY,INFINITY,INFINITY,INFINITY},
{5,INFINITY,INFINITY,INFINITY,40,10,INFINITY,INFINITY,50,INFINITY,INFINITY,INFINITY,25,INFINITY},
{INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,25,INFINITY,20},
{INFINITY,10,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,100,INFINITY,INFINITY,20,INFINITY},};
MGraph G = new MGraph(GraphKind.UDN, 14, 19, vexs, arcs);
return G;
}
}
package sy10;
// 图的种类 有向图、有向网、无向图、无向网
public enum GraphKind {
UDG, // 无向图(UnDirected Graph)
DG, // 有向图(Directed Graph)
UDN, // 无向网(UnDirected Network)
DN; // 有向网(Directed Network)
}
package sy10;
//图的接口
public interface IGraph {
void createGraph();//创建一个图
int getVexNum(); // 返回顶点数
int getArcNum();// 返回边数
Object getVex(int v) throws Exception;// 返回v表示结点的值, 0 <= v < vexNum
int locateVex(Object vex);// 给定顶点的值vex,返回其在图中的位置,如果图中不包含此顶点,则返回-1
int firstAdjVex(int v) throws Exception; // 返回v的第一个邻接点,若v没有邻接点,则返回-1,其中0≤v<vexNum
int nextAdjVex(int v, int w) throws Exception;// 返回v相对于w的下一个邻接点,若w是v的最后一个邻接点,则返回-1,其中0≤v, w<vexNum
}
package sy10;
/**
*
* 线性表的接口
*
*/
public interface IList {
public void clear(); // 将一个已经存在的线性表置成空表
public boolean isEmpty(); // 判断当前线性表中的数据元素个数是否为0,若为0则函数返回true,否则返回false
public int length(); // 求线性表中的数据元素个数并由函数返回其值
public Object get(int i) throws Exception;// 读取到线性表中的第i个数据元素并由函数返回其值。其中i取值范围为:0≤i≤length()-1,如果i值不在此范围则抛出异常
public void insert(int i, Object x) throws Exception;// 在线性表的第i个数据元素之前插入一个值为x的数据元素。其中i取值范围为:0≤i≤length()。如果i值不在此范围则抛出异常,当i=0时表示在表头插入一个数据元素x,当i=length()时表示在表尾插入一个数据元素x
public void remove(int i) throws Exception;// 将线性表中第i个数据元素删除。其中i取值范围为:0≤i≤length()- 1,如果i值不在此范围则抛出异常
public int indexOf(Object x);// 返回线性表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1
public void display();// 输出线性表中的数据元素
}
package sy10;
import java.util.Scanner;
//图的数组表示法
public class MGraph implements IGraph {
public final static int INFINITY = Integer.MAX_VALUE;
private GraphKind kind;// 图的种类标志
private int vexNum, arcNum;// 图的当前顶点数和边数
private Object[] vexs;// 顶点
private int[][] arcs;// 邻接矩阵
public MGraph() {
this(null, 0, 0, null, null);
}
public MGraph(GraphKind kind, int vexNum, int arcNum, Object[] vexs,
int[][] arcs) {
this.kind = kind;
this.vexNum = vexNum;
this.arcNum = arcNum;
this.vexs = vexs;
this.arcs = arcs;
}
// 创建一个图
public void createGraph() {
Scanner sc = new Scanner(System.in);
System.out.println("请输入图的类型:");
GraphKind kind = GraphKind.valueOf(sc.next());
switch (kind) {
case UDG:
createUDG();// 构造无向图
return;
case DG:
createDG();// 构造有向图
return;
case UDN:
createUDN();// 构造无向网
return;
case DN:
createDN();// 构造有向网
return;
}
}
// 创建无向图
private void createUDG() {
// 略
Scanner sc = new Scanner(System.in);
System.out.println("请分别输入图的顶点数、图的变数:");
vexNum = sc.nextInt();
arcNum = sc.nextInt();
vexs = new Object[vexNum];
System.out.println("请分别输入图的各个顶点:");
for (int v = 0; v < vexNum; v++)
vexs[v] = sc.next();
arcs = new int[vexNum][vexNum];
for (int v = 0; v < vexNum; v++)
for ( int u = 0; u < vexNum; u++)
arcs[v][u] = 0;
System.out.println("请输入各个边的两个顶点");
for (int k = 0; k < arcNum; k++){
int v = locateVex(sc.next());
// System.out.println(locateVex(sc.next()));
// System.out.println(v);
int u = locateVex(sc.next());
arcs[v][u] = arcs[u][v] = 1;
}
}
// 创建有向图
private void createDG() {
}
// 创建无向网
private void createUDN() {
Scanner sc = new Scanner(System.in);
System.out.println("请分别输入图的顶点数、图的边数:");
vexNum = sc.nextInt();
arcNum = sc.nextInt();
vexs = new Object[vexNum];
System.out.println("请分别输入图的各个顶点:");
for (int v = 0; v < vexNum; v++)
// 构造顶点向量
vexs[v] = sc.next();
arcs = new int[vexNum][vexNum];
for (int v = 0; v < vexNum; v++)
// 初始化邻接矩阵
for (int u = 0; u < vexNum; u++)
arcs[v][u] = INFINITY;
System.out.println("请输入各个边的顶点及其权值:");
for (int k = 0; k < arcNum; k++) {
int v = locateVex(sc.next());
int u = locateVex(sc.next());
arcs[v][u] = arcs[u][v] = sc.nextInt();
}
}
// 创建有向网
private void createDN() {
Scanner sc = new Scanner(System.in);
System.out.println("请分别输入图的顶点数、图的边数:");
vexNum = sc.nextInt();
arcNum = sc.nextInt();
vexs = new Object[vexNum];
System.out.println("请分别输入图的各个顶点:");
for (int v = 0; v < vexNum; v++)
// 构造顶点向量
vexs[v] = sc.next();
arcs = new int[vexNum][vexNum];
for (int v = 0; v < vexNum; v++)
// 初始化邻接矩阵
for (int u = 0; u < vexNum; u++)
arcs[v][u] = INFINITY;
System.out.println("请输入各边的顶点及其权值:");
for (int k = 0; k < arcNum; k++) {
int v = locateVex(sc.next());
int u = locateVex(sc.next());
arcs[v][u] = sc.nextInt();
}
}
// 返回顶点数
public int getVexNum() {
return vexNum;
}
// 返回边数
public int getArcNum() {
return arcNum;
}
// 给定顶点的值vex,返回其在图中的位置,如果图中不包含此顶点,则返回-1
public int locateVex(Object vex) {
for (int v = 0; v < vexNum; v++)
if (vexs[v].equals(vex))
return v;
return -1;
}
// 返回v表示结点的值, 0 <= v < vexNum
public Object getVex(int v) throws Exception {
if (v < 0 && v >= vexNum)
throw new Exception("第" + v + "个顶点不存在!");
return vexs[v];
}
// 返回v的第一个邻接点,若v没有邻接点则返回-1, 0 <= v < vexnum
public int firstAdjVex(int v) throws Exception {
if (v < 0 && v >= vexNum)
throw new Exception("第" + v + "个顶点不存在!");
for (int j = 0; j < vexNum; j++)
if (arcs[v][j] != 0 && arcs[v][j] < INFINITY)
return j;
return -1;
}
// 返回v相对于w的下一个邻接点,若w是v的最后一个邻接点,则返回-1,其中0≤v, w<vexNum
public int nextAdjVex(int v, int w) throws Exception {
if (v < 0 && v >= vexNum)
throw new Exception("第" + v + "个顶点不存在!");
for (int j = w + 1; j < vexNum; j++)
if (arcs[v][j] != 0 && arcs[v][j] < INFINITY)
return j;
return -1;
}
public GraphKind getKind() {
return kind;
}
public void setArcNum(int arcNum) {
this.arcNum = arcNum;
}
public void setArcs(int[][] arcs) {
this.arcs = arcs;
}
public void setKind(GraphKind kind) {
this.kind = kind;
}
public void setVexNum(int vexNum) {
this.vexNum = vexNum;
}
public void setVexs(Object[] vexs) {
this.vexs = vexs;
}
public int[][] getArcs() {
return arcs;
}
public Object[] getVexs() {
return vexs;
}
}
package sy10;
public class ShortestPath_DIJ {
private boolean[][] P;// v0到其余顶点的最短路径, 若P[v][w]为true,则w是从v0到v当前求得最短路径上的顶点
private int[] D;// v0到其余顶点的带权长度
public final static int INFINITY = Integer.MAX_VALUE;
// 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及其权值D[v]
public void DIJ(MGraph G, int v0) {
int vexNum = G.getVexNum();
P = new boolean[vexNum][vexNum];
D = new int[vexNum];
boolean[] finish = new boolean[vexNum];// finish[v]为true当且仅当v属于S,即已经求得从v0到v的最短路径
for (int v = 0; v < vexNum; v++) {
finish[v] = false;
D[v] = G.getArcs()[v0][v];
for (int w = 0; w < vexNum; w++)
P[v][w] = false;// 设空路径
if (D[v] < INFINITY) {
P[v][v0] = true;
P[v][v] = true;
}
}
D[v0] = 0;// 初始化,v0顶点属于S集
finish[v0] = true;
int v = -1;
// 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集
for (int i = 1; i < vexNum; i++) {// 其余G.getVexNum-1个顶点
int min = INFINITY;// 当前所知离v0顶点的最近距离
for (int w = 0; w < vexNum; w++)
if (!finish[w])
if (D[w] < min) {
v = w;
min = D[w];
}
finish[v] = true;// 离v0顶点最近的v加入S集
for (int w = 0; w < vexNum; w++)
// 更新当前最短路径及距离
if (!finish[w] && G.getArcs()[v][w] < INFINITY
&& (min + G.getArcs()[v][w] < D[w])) { // 修改D[w]和P[w],w属于V-S
D[w] = min + G.getArcs()[v][w];
System.arraycopy(P[v], 0, P[w], 0, P[v].length);
P[w][w] = true;
}
}
}
public int[] getD() {
return D;
}
public boolean[][] getP() {
return P;
}
// public static void main(String[] args) throws Exception {
// MGraph G = GenerateGraph.generateMGraph();
// ShortestPath_DIJ dij = new ShortestPath_DIJ();
// dij.DIJ(G, 0);
dij.display(G);
// }
// 用于输出最短路径上的各各顶点及权值
public void display(MGraph G,int b, int r) throws Exception {
if (D != null) {
System.out.println(G.getVex(b)+"到各各顶点的最短路径上的点及最短距离分别是:");
System.out.println();
// System.out.print( G.getVex(b) + "到" + G.getVex(r) + "请沿着这条路走,是最短的距离: ");
for (int i = 0; i < P.length; i++) {
System.out.print(i+" ");
System.out.print( G.getVex(b) + " 到 " + G.getVex(i) + "请沿着这条路走,是最短的距离: ");
System.out.println();
for (int j = 0; j < P[i].length; j++) {
if (P[i][j])
// System.out.println("请沿着这条路线走,距离最短,");
System.out.print(G.getVex(j) + " ");
}
System.out.println();
System.out.println("最短距离为: " + D[i] +"米");
System.out.println();
}
System.out.println("因此"+G.getVex(b) + " 到 " + G.getVex(r) + "最短距离为: " + D[r] +"米");
}
}
}
package sy10;
/**
*
* 顺序线性表及其基本操作
*
*/
public class SqList implements IList {
private Object[] listElem; // 线性表存储空间
private int curLen; // 当前长度
// 顺序表的构造函数,构造一个存储空间容量为maxSize的线性表
public SqList(int maxSize) {
curLen = 0; // 置顺序表的当前长度为0
listElem = new Object[maxSize];// 为顺序表分配maxSize个存储单元
}
// 将一个已经存在的线性表置成空表
public void clear() {
curLen = 0; // 置顺序表的当前长度为0
}
// 判断当前线性表中数据元素个数是否为0,若为0则函数返回true,否则返回false
public boolean isEmpty() {
return curLen == 0;
}
// 求线性表中的数据元素个数并由函数返回其值
public int length() {
return curLen; // 返回顺序表的当前长度
}
// 读取到线性表中的第i个数据元素并由函数返回其值。其中i取值范围为:0≤i≤length()-1,如果i值不在此范围则抛出异常
public Object get(int i) throws Exception {
if (i < 0 || i > curLen - 1) // i小于0或者大于表长减1
throw new Exception("第" + i + "个元素不存在"); // 输出异常
return listElem[i]; // 返回顺序表中第i个数据元素
}
// 在线性表的第i个数据元素之前插入一个值为x的数据元素。其中i取值范围为:0≤i≤length()。如果i值不在此范围则抛出异常,当i=0时表示在表头插入一个数据元素x,当i=length()时表示在表尾插入一个数据元素x
public void insert(int i, Object x) throws Exception {
if (curLen == listElem.length) // 判断顺序表是否已满
throw new Exception("顺序表已满");// 输出异常
if (i < 0 || i > curLen) // i小于0或者大于表长
throw new Exception("插入位置不合理");// 输出异常
for (int j = curLen; j > i; j--)
listElem[j] = listElem[j - 1];// 插入位置及之后的元素后移
listElem[i] = x; // 插入x
curLen++;// 表长度增1
}
// 将线性表中第i个数据元素删除。其中i取值范围为:0≤i≤length()- 1,如果i值不在此范围则抛出异常
public void remove(int i) throws Exception {
if (i < 0 || i > curLen - 1) // i小于1或者大于表长减1
throw new Exception("删除位置不合理");// 输出异常
for (int j = i; j < curLen - 1; j++)
listElem[j] = listElem[j + 1];// 被删除元素之后的元素左移
curLen--; // 表长度减1
}
// 返回线性表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1
public int indexOf(Object x) {
int j = 0;// j为计数器
while (j < curLen && !listElem[j].equals(x))
// 从顺序表中的首结点开始查找,直到listElem[j]指向元素x或到达顺序表的表尾
j++;
if (j < curLen)// 判断j的位置是否位于表中
return j; // 返回x元素在顺序表中的位置
else
return -1;// x元素不在顺序表中
}
// 输出线性表中的数据元素
public void display() {
for (int j = 0; j < curLen; j++)
System.out.print(listElem[j] + " ");
System.out.println();// 换行
}
// 实现对顺序表就地逆置
public void reverse() {
for (int i = 0,j=curLen-1; i < j; i++,j--) {
Object temp = listElem[i];
listElem[i] = listElem[j];
listElem[j] = temp;
}
}
// 实现对顺序表右移k位
public void shit(int k) {
int n=curLen,p=0,i,j,l;
Object temp;
for(i=1;i<=k;i++)
if(n%i==0&&k%i==0) //求n和k的最大公约数p
p=i;
for(i=0;i<p;i++){
j=i;
l=(i+n-k)%n;
temp=listElem[i];
while(l!=i){
listElem[j]=listElem[l];
j=l;
l=(j+n-k)%n;
}// 循环右移一步
listElem[j]=temp;
}
}
}
package sy10;
import java.util.Scanner;
public class SY10_Graph1{
public static void main(String[] args) throws Exception{
SqList L = new SqList(14);
L.insert(0, "这里是正门,代号为0,历史悠久,距离礼堂5米,距离食堂35米");
L.insert(1, "这里是学校的东校门,代号为1,校门历史悠久,距离游泳馆75米,距离宿舍10米,具体体育馆100米");
L.insert(2, "这里是西校门,代号2, 距离图书馆5米,距离食堂30米");
L.insert(3," 这里是北校门,代号为3, 距离图书馆50米,距离樱花大道15米,距离体育馆9米,距离游泳馆20米");
L.insert(4, "这里是食堂,代号4, 距离……介绍……此处是省略相关的信息");
L.insert(5, "这是磁悬浮列车实验室,代号5,介绍……此处是省略相关的信息");
L.insert(6, "这里是樱花大道, 代号6, 介绍……此处是省略相关的信息");
L.insert(7, "这里是图书馆,代号7 , 介绍……此处是省略相关的信息");
L.insert(8, "这里是体育馆,代号8, 介绍……此处是省略相关的信息");
L.insert(9, "这里是体育馆,代号9, 介绍……此处是省略相关的信息");
L.insert(10, "这里是游泳馆,代号10, 介绍……此处是省略相关的信息");
L.insert(11, "这里是礼堂,代号11, 介绍……此处是省略相关的信息");
L.insert(12, "这里是教学楼,代号12,介绍……此处是省略相关的信息");
L.insert(13, "这里是宿舍,代号13,介绍……此处是省略相关的信息");
Scanner sc = new Scanner(System.in);
while (true){
System.out.println("请输入你想了解的景区地方:");
System.out.println("----------------------------------------");
System.out.println("0--正门 1--东门 2--西门 3--北校门 4--食堂");
System.out.println("5--磁悬浮列车实验室 6--樱花大道 7--图书馆 8--体育场 9--体育馆");
System.out.println("10--游泳馆 11--礼堂 12--教学楼 13--宿舍 14-选择最短路径 15--退出");
System.out.println("----------------------------------------");
System.out.println("请输入选择:(0 - 15)");
int i = sc.nextInt();
switch (i){
case 0: System.out.println("正校门情况为:");
System.out.println(L.get(0));break;
case 1: System.out.println("东校门情况为:");
System.out.println(L.get(1));break;
case 2: System.out.println("西校门情况:");
System.out.println(L.get(2));break;
case 3: System.out.println("北校门情况为:");
System.out.println(L.get(3));break;
case 4: System.out.println("食堂情况为:");
System.out.println(L.get(4));break;
case 5: System.out.println("磁悬浮列车实验室情况为:");
System.out.println(L.get(5));break;
case 6: System.out.println("樱花大道情况为:");
System.out.println(L.get(6));break;
case 7: System.out.println("图书馆情况为:");
System.out.println(L.get(7));break;
case 8: System.out.println("体育场情况为:");
System.out.println(L.get(8));break;
case 9: System.out.println("体育馆情况为:");
System.out.println(L.get(9));break;
case 10: System.out.println("游泳馆情况为:");
System.out.println(L.get(10));break;
case 11: System.out.println("礼堂情况为:");
System.out.println(L.get(11));break;
case 12: System.out.println("教学楼情况为:");
System.out.println(L.get(12));break;
case 13: System.out.println("宿舍情况为:");
System.out.println(L.get(13));break;
case 14: System.out.println("输入你想要去的两个地方,计算机帮你计算最小距离,用数字输入");
// ShortestPath_DIJ little = new ShortestPath_DIJ();
// Object first = sc.next();
// Object second = sc.next();
// little.DIJ(G, 0);
int v = sc.nextInt();
int s = sc.nextInt();
MGraph G = GenerateGraph.generateMGraph();
ShortestPath_DIJ dij = new ShortestPath_DIJ();
dij.DIJ(G, v);
dij.display(G,v, s);
break;
case 15: return;
}
}
}
}
这是用java写成的关于学校内各个景点见得最短路径,把上面的每个代码分别放到一个.Java文件当中,写成八个文件,最后调用主类就可以得到想要的,我试过了,挺好的