20192304 实验九《数据结构和面向对象的程序设计》 实验报告

课程:《程序设计与数据结构》
班级: 1923
姓名: 刘润衡
学号:20192304
实验教师:王志强
实验日期:2020年12月25日
必修/选修: 必修

1.实验内容
(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分)
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分)
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分)

  1. 实验过程及结果
    (1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义

(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)

(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)

(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出

(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)

  1. 实验过程中遇到的问题和解决过程
    问题1:图加权等内容输入错误
    问题1解决方案:先在草稿纸上面写好了在输。
    其他(感悟、思考等)
    图作为一种逻辑结构,是对于设计的人很清楚却对于别人很摸不到头脑的东西。不了解排序方法的人不能很顺手地了解。
    代码

    import java.util.*;

public class Graph {

static int dot, side;
static int[][] concern = new int[15][15];
static int[] link = new int[30];
static int[] visited = new int[15];
static int[] visited2 = new int[15];
static Scanner scan = new Scanner(System.in);
static int origin, weight = 0;
static int total2 = 0;
static int temp = 9999, temp2 = 0;
static int[] dist = new int[15];
static int[] pre = new int[15];
static Queue list = new LinkedList();
static Stack stack = new Stack();
static Stack stack2 = new Stack();

public static void main(String[] args) {
    System.out.println("无向图就点1搞快点");
    System.out.println("有向图就按2没问题");
    int select;
    do{ select = scan.nextInt();
        if(select == 1){
            CreateUndigraph();
        }
        if(select == 2){
            CreateDigraph(); }
    }while (select != 1 && select != 2);
    Adjacency_Matrix();
    origin = search();
    System.out.println("广度优先");
    Breadth_Traversal(origin);
    for(int i = 0; i < dot; i++){
        visited[i] = 0;
    }
    System.out.println("\n深度优先");
    Depth_Traversal(origin);
    if(select == 1){
        System.out.println("\nPrim、最小生成树:");
        for(int i = 0; i < dot; i++){
            visited[i] = 0;
        }
        for(int i = 0; i < dot; i++){
            for(int j = 0; j < dot; j++){
                if(concern[i][j] == 1){
                    System.out.print(  (i+1) + " " + (j+1) + "两顶点之间边的权值:");
                    concern[i][j] = scan.nextInt();
                    concern[j][i] = concern[i][j];
                }
            }
        }
        System.out.print("起始顶点是哪一个?:");
        int v = scan.nextInt();
        Prim(concern, v);
        System.out.println("最小权值:" + weight);
    }
    if(select == 2){
        System.out.println("        1:有向图的拓扑排序");
        System.out.println("     2:有向图的单源最短路径求解");
        do{
            select = scan.nextInt();
        }while (select != 1 && select != 2);
        if(select == 1){
            System.out.println("拓扑排序:");
            total2 = 0;
            for(int i = 0; i < dot; i++){
                visited[i] = 0;
            }
            Topology(concern);
        }
        if(select == 2){
            System.out.println("用迪杰斯特拉算法完成有向图的单源最短路径求解:");
            for(int i = 0; i < dot; i++){
                visited[i] = 0;
            }
            System.out.print("请输入起始顶点编号(起点入度为0):");
            int v = scan.nextInt();
            //visited[v] = 1;
            for(int i = 0; i < dot; i++){
                for(int j = 0; j < dot; j++){
                    if(concern[i][j] == 1){
                        System.out.print( (i+1) + " " + (j+1) + "两顶点之间边的权值:");
                        concern[i][j] = scan.nextInt();
                    }
                }
            }
            for(int i = 0; i < dot; i++){
                dist[i] = concern[v - 1][i];
                if(concern[v - 1][i] != 0){
                    pre[i] = 1;
                }
            }
            for(int i = 0; i < dot; i++){
                if(dist[i] != 0 && dist[i] < temp){
                    temp = dist[i];
                    temp2 = i;
                }
            }
            concern[v-1][v-1] = 1;
            //System.out.print(v + " ");
            total2 = 1;
            Dijkstra(concern, temp2 + 1);
            for(int i = 0; i < dot; i++){
                if(i+1 != v){
                    int tempp = i;
                    while (pre[tempp] != 0){
                        stack2.push(tempp + 1);
                        tempp = pre[tempp] - 1;
                    }
                    System.out.print(v + "到" + (i+1) + "的最短路径为:" + v + " ");
                    while (!stack2.isEmpty()){
                        System.out.print(stack2.pop() + " ");
                    }
                    System.out.println("长度:" + dist[i]);
                }
            }
        }
    }
}

public static void CreateUndigraph(){
    System.out.print("顶点数:");
    dot = scan.nextInt();
    System.out.print("边数:");
    side = scan.nextInt();
    int j = 0;
    for(int i = 0; i < side; i++){
        System.out.print( (i+1) + "条边相连的两点:");
        link[j] = scan.nextInt();
        link[j + 1] = scan.nextInt();
        j = j + 2;
    }
    for(int i = 0; i < j; i = i + 2){
        concern[link[i] - 1][link[i+1] - 1] = 1;
        concern[link[i+1] - 1][link[i] - 1] = 1;
    }
}

public static void CreateDigraph(){
    System.out.print("顶点数:");
    dot = scan.nextInt();
    System.out.print("边数:");
    side = scan.nextInt();
    int j = 0;
    for(int i = 0; i < side; i++){
        System.out.print((i+1) + "条边首尾相连的两点:");
        link[j] = scan.nextInt();
        link[j + 1] = scan.nextInt();
        j = j + 2;
    }
    for(int i = 0; i < j; i = i + 2){
        concern[link[i] - 1][link[i+1] - 1] = 1;
    }
}

public static void Adjacency_Matrix(){
    System.out.println("该图的邻接矩阵为:");
    for(int i = 0; i < dot; i++){
        for(int j = 0; j < dot; j++){
            System.out.print(concern[i][j] + " ");
        }
        System.out.println();
    }
}

public static int search(){
    int origin = 0, temp = 0, temp2 = 0;
    for(int i = 0; i < dot; i++){
        for(int j = 0; j < dot; j++){
            if(concern[i][j] == 1){
                temp++;
            }
        }
        if(temp > temp2){
            origin = i + 1;
            temp2 = temp;
        }
        temp = 0;
    }
    return origin;
}

public static void Breadth_Traversal(int origin){
    if(visited[origin - 1] != 1 ) {
        System.out.print(origin + " ");
        visited[origin - 1] = 1;
    }
    for(int i = 0; i < dot; i++){
        if(concern[origin - 1][i] == 1){
            if(visited[i] != 1 ) {
                System.out.print((i + 1) + " ");
                list.add(i + 1);
                visited[i] = 1;
            }
        }
    }
    while(!list.isEmpty()){
        int temp = (int) list.poll();
        Breadth_Traversal(temp);
    }
}

public static void Depth_Traversal(int origin){
    if(visited[origin - 1] != 1 ) {
        System.out.print(origin + " ");
        visited[origin - 1] = 1;
    }
    for(int i = 0; i < dot; i++){
        if(concern[origin - 1][i] == 1){
            if(visited[i] != 1 ) {
                System.out.print((i + 1) + " ");
                visited[i] = 1;
                Depth_Traversal(i + 1);
            }
        }
    }
}

public static void Topology(int AdjMatrix[][]){
    int i ,j, total = 0, temp2 = 0;
    for(j = 0; j < dot; j++){
        for (i = 0; i < dot; i++){
            if(AdjMatrix[i][j] == 0)
                total++;
            if(AdjMatrix[i][j] == 1)
                break;
        }
        if(total == dot && visited[j] != 1){
            stack.push(j);
            visited[j] = 1;
            temp2++;
        }
        total = 0;
    }
    while (!stack.isEmpty()){
        int temp = (int) stack.pop();
        for(int k = 0; k <dot; k++){
            AdjMatrix[temp][k] = 0;
        }
        System.out.print((temp+1) + " ");
        total2++;
    }
    if(total2 < dot && temp2 != 0){
        Topology(AdjMatrix);
    }if(total2 < dot && temp2 == 0){
        System.out.println("存在环,停止拓扑");
    }
}

public static void Prim(int AdjMatrix[][], int v){
    int k;
    int temp = 9999, temp2 = 0, temp3 = 0;
    visited2[total2] = v;
    total2++;
    for(int i = 0; i < total2; i++){
        for(k = 0; k < dot; k++){
            if(AdjMatrix[visited2[i] - 1][k] > 0 && AdjMatrix[visited2[i] - 1][k] < temp && visited[k] != 1){
                temp = AdjMatrix[visited2[i] - 1][k];
                temp2 = k;
                temp3 = visited2[i] - 1;
            }
        }
    }
    visited[temp3] = 1;
    visited[temp2] = 1;
    AdjMatrix[temp3][temp2] = -1;
    AdjMatrix[temp2][temp3] = -1;
    weight += temp;
    if(total2  < dot - 1){
        Prim(AdjMatrix, temp2 + 1);
    }else {
        System.out.println("该最小生成树的图的邻接矩阵为:");
        for(int i = 0; i < dot; i++){
            for(int j = 0; j < dot; j++){
                if(AdjMatrix[i][j] == -1){
                    AdjMatrix[i][j] = 1;
                }else {
                    AdjMatrix[i][j] = 0;
                }
                System.out.print(AdjMatrix[i][j] + " ");
            }
            System.out.println();
        }
    }
}

public static void Dijkstra(int AdjMatrix[][], int v){
    int temp = 9999, temp2 = 0, j;
    //System.out.print(v + " ");
    AdjMatrix[v-1][v-1] = 1;
    for (j = 0; j < dot; j++){
        if(AdjMatrix[v-1][j] != 0 && j != v-1) {
            if(dist[j] == 0 || dist[j] > dist[v-1] + AdjMatrix[v-1][j]) {
                dist[j] = dist[v - 1] + AdjMatrix[v - 1][j];
                pre[j] = v;
            }
        }
    }
    for(int i = 0; i < dot; i++){
        if(dist[i] != 0 && dist[i] < temp && AdjMatrix[i][i] != 1){
            temp = dist[i];
            temp2 = i;
        }
    }
    total2++;
    if(total2 < dot) {
        Dijkstra(AdjMatrix, temp2 + 1);
    }
}

}
https://gitee.com/besti1923/lrh20192304_JAVAProgramrr/commit/75c8a41d6d8a89cc99cc426ed0a945fcaf001b05
参考资料
《Java程序设计与数据结构教程(第二版)》

《Java程序设计与数据结构教程(第二版)》学习指导

...

图片现在流量实在是传不上去,明早补充。

posted @ 2020-12-27 23:35  20192304刘润衡  阅读(92)  评论(0编辑  收藏  举报