20192304 实验九《数据结构和面向对象的程序设计》 实验报告
课程:《程序设计与数据结构》
班级: 1923
姓名: 刘润衡
学号:20192304
实验教师:王志强
实验日期:2020年12月25日
必修/选修: 必修
1.实验内容
(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分)
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分)
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分)
- 实验过程及结果
(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)
- 实验过程中遇到的问题和解决过程
问题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程序设计与数据结构教程(第二版)》学习指导
...
图片现在流量实在是传不上去,明早补充。