課程:《程序設計與數據結構》
班級: 1823
姓名: 魏冰妍
學號:20182330
實驗教師:王志強
實驗日期:2019年12月2日
必修/選修: 必修html
完成圖的綜合實踐
(1)初始化:根據屏幕提示(例如:輸入1爲無向圖,輸入2爲有向圖)初始化無向圖和有向圖(可用鄰接矩陣,也可用鄰接表),圖須要本身定義(頂點個數、邊個數,建議先在草稿紙上畫出圖,而後再輸入頂點和邊數)
(2)圖的遍歷:完成有向圖和無向圖的遍歷(深度和廣度優先遍歷)
(3)完成有向圖的拓撲排序,並輸出拓撲排序序列或者輸出該圖存在環
(4)完成無向圖的最小生成樹(Prim算法或Kruscal算法都可),並輸出
(5)完成有向圖的單源最短路徑求解(迪傑斯特拉算法)java
1.初始化:根據屏幕提示(例如:輸入1爲無向圖,輸入2爲有向圖)初始化無向圖和有向圖(可用鄰接矩陣,也可用鄰接表),圖須要本身定義(頂點個數、邊個數,建議先在草稿紙上畫出圖,而後再輸入頂點和邊數)node
public Sorting(char[] dingdian, EData[] bian) { int lenv = dingdian.length; int elen = bian.length; // 初始化頂點 mV= new N[lenv]; for (int i = 0; i < mV.length; i++) { mV[i] = new N(); mV[i].dingdian = dingdian[i]; mV[i].firstX = null; } // 初始化邊 Enum = elen; for (int i = 0; i < elen; i++) { // 讀取頂點 char c1 = bian[i].start; char c2 = bian[i].end; int weight = bian[i].weight; int p1 = gPs(c1); int p2 = gPs(c2); B node1 = new B (); node1.i = p2; node1.w = weight; //鏈接 if(mV[p1].firstX == null) mV[p1].firstX = node1; else Connect(mV[p1].firstX, node1); B node2 = new B (); node2.i = p1; node2.w = weight; //鏈接 if(mV[p2].firstX == null) mV[p2].firstX = node2; else Connect(mV[p2].firstX, node2); } }
2.圖的遍歷:完成有向圖和無向圖的遍歷(深度和廣度優先遍歷)算法
private void DFS(int i, boolean[] BL) { B node; BL[i] = true; System.out.printf("%c ", mV[i].dingdian); node = mV[i].firstX; while (node != null) { if (!BL[node.i]) DFS(node.i, BL); node = node.nextX; } }
public void BFS() { int head = 0; int rear = 0; int[] queue = new int[mV.length]; // 輔組隊列 boolean[] BL = new boolean[mV.length]; // 頂點訪問標記 for (int i = 0; i < mV.length; i++) BL[i] = false; System.out.printf("廣度優先遍歷: "); for (int i = 0; i < mV.length; i++) { if (!BL[i]) { BL[i] = true; System.out.printf("%c ", mV[i].dingdian); queue[rear++] = i; // 入隊列 } while (head != rear) { int j = queue[head++]; // 出隊列 B node = mV[j].firstX; while (node != null) { int k = node.i; if (!BL[k]) { BL[k] = true; System.out.printf("%c ", mV[k].dingdian); queue[rear++] = k; } node = node.nextX; } } } System.out.printf("\n"); }
3.完成有向圖的拓撲排序,並輸出拓撲排序序列或者輸出該圖存在環數組
public int TpSort() { int index = 0; int num = mV.length; int[] ins; // 入度數組 char[] tops; Queue<Integer> queue; ins = new int[num]; tops = new char[num]; queue = new LinkedList<Integer>(); // 統計每一個頂點的入度數 for(int i = 0; i < num; i++) { B node = mV[i].firstX; while (node != null) { ins[node.i]++; node = node.nextX; } } // 將全部入度爲0的頂點入隊列 for(int i = 0; i < num; i ++) if(ins[i] == 0) queue.offer(i); // 入隊列 while (!queue.isEmpty()) { // 隊列非空 int j = queue.poll().intValue(); // 出隊列。j是頂點的序號 tops[index++] = mV[j].dingdian; B node = mV[j].firstX; while(node != null) { // 入度減1。 ins[node.i]--; // 若入度爲0,則入隊列 if( ins[node.i] == 0) queue.offer(node.i); // 入隊列 node = node.nextX; } } if(index != num) { System.out.printf("有向有環圖\n"); return 1; } // 打印拓撲排序結果 System.out.printf("拓撲排序: "); for(int i = 0; i < num; i ++) System.out.printf("%c ", tops[i]); System.out.printf("\n"); return 0; }
public void kruskal() { int index = 0; int[] v = new int[Enum]; // 保存終點。 EData[] rets = new EData[Enum]; // 暫存結果數組 EData[] e; // 對應的全部邊 e = getEdges(); // 將邊按權排序 sortEdges(e, Enum); for (int i=0; i<Enum; i++) { int p1 = gPs(e[i].start); int p2 = gPs(e[i].end); int m = getEnd(v, p1); int n = getEnd(v, p2); // 若是m!=n,則沒有造成環路 if (m != n) { v[m] = n; rets[index++] = e[i]; } } }
5.完成有向圖的單源最短路徑求解(迪傑斯特拉算法)數據結構
public void dijkstra(int s, int[] q, int[] t) { // flag[i]=true表示最短路徑已成功獲取。 boolean[] flag = new boolean[mV.length]; // 初始化 for (int i = 0; i < mV.length; i++) { flag[i] = false; q[i] = 0; // 頂點i的前驅頂點爲0。 t[i] = getWeight(s, i); } // 初始化 flag[s] = true; t[s] = 0; int k = 0; for (int i = 1; i < mV.length; i++) { // 尋找當前最小的路徑; // 尋找當前最小的路徑; // 尋找當前最小的路徑; int min = INF; for (int j = 0; j < mV.length; j++) { if (flag[j]==false && t[j]<min) { min = t[j]; k = j; } } // 獲取到最短路徑 flag[k] = true; for (int j = 0; j < mV.length; j++) { int tmp = getWeight(k, j); tmp = (tmp==INF ? INF : (min + tmp)); // 防止溢出 if (flag[j]==false && (tmp<t[j]) ) { t[j] = tmp; q[j] = k; } } }
問題1:try異常致使程序鎖死。app
問題1解決方案:解決時發現不止我一我的有這個問題。參照博客發現是e.printStackTrace()
。因而刪掉 e.printStackTrace() ,異常處理。學習
短期內大量請求訪問此接口 -> 代碼自己有問題,不少狀況下拋異常 -> e.printStackTrace() 來打印異常到控制檯 -> 產生錯誤堆棧字符串到字符串池內存空間 -> 此內存空間一會兒被佔滿了 -> 開始在此內存空間產出字符串的線程還沒徹底生產完整,就沒空間了 -> 大量線程產出字符串產出到一半,等在這兒(等有內存了繼續搞啊)-> 相互等待,等內存,鎖死了,整個應用掛掉了。.net
最後一個小實驗,我的認爲圖的理解比樹簡單一點,而且能夠利用到離散中學過的知識。java結課意味着接下來能夠安心複習期末和準備app了。線程