無向圖就是邊全爲無序結點對的圖
html
注意區分:若是無向圖擁有最大數目的連通頂點的邊,則無向圖是徹底的;若是無向圖中任意兩個頂點之間都存在一條路徑,則認爲無向圖是連通的。如圖是非連通無向圖,D與另外三個頂點之間均沒有任何路徑。
java
無向樹是一種連通的無環無向圖,其中一個元素被指定爲樹根node
有向圖也稱雙向圖,是一種邊爲有序頂點對的圖,邊(A,B)和(B,A)是不一樣的有向邊
git
如有向圖中任意兩個頂點之間都存在一條路徑,則認爲該有向圖是連通的。下圖中第一個圖是連通的,第二個圖不是,由於沒有任何路徑能從其它頂點遊歷到1,也不能從6出發遊歷任何其餘頂點
算法
無向連通圖及以每一個頂點爲起點的廣度優先遍歷
無向非連通圖及以每一個頂點爲起點的廣度優先遍歷
數組
問題一解決:經過查找資料其過程可認爲:網絡
廣度優先遍歷(使用一個隊列):二者之間惟一不一樣之處是:深度優先遍歷使用棧而不是隊列來管理遍歷學習
問題二解決:鄰接列表是對每一個頂點創建一個鏈表,表示以改頂點爲起點的全部頂點。經過訪問一個頂點的鏈表便可得出該頂點的全部邊。由此也可也得出以改頂點爲起點的一條路徑。
有向圖:
一共有1234四個頂點,因此創建四個頂點,以1爲起點的有234,以2爲起點的只有4,以3爲起點的沒有,以4爲起點的只有3。
無向圖:
一共有ABCD四個頂點,創建4個鏈表。A頂點鏈接的邊是BCD,與B頂點鏈接的是ABD,與C頂點鏈接的只有A,與D頂點鏈接的是AB。測試
問題一:在iteratorBFS方法中,spa
if (!indexIsValid(startIndex)) return resultList.iterator();不清楚iterator方法的做用
在類聲明中加入implements Iterable
public interface Iterable<Item>{ Iterator<Item> iterator(); }
在類中實現iterator()方法,返回一個本身定義的迭代器Iterator
public Iterator<Item> iterator(){ //若是須要逆序遍歷數組,自定義一個逆序迭代數組的迭代器 return new ReverseArrayIterator(); }
在類中設置內部類(如private class ReverseArrayIterator() ),內部類聲明中加入implements Iterator
public interface Iterator { boolean hasNext(); Object next(); void remove(); }
這些是在第四周中學到過的,好比ArrayList類,徹底符合以上步驟。
在這裏,因爲索引無效,必需要返回一個相同類型的值,實際上就是空的。
問題二解決:見註釋
private Iterator<T> iteratorBFS(int startIndex) { Integer x; QueueADT<Integer> traversalQueue = new LinkedQueue<Integer>(); UnorderedListADT<T> resultList = new ArrayUnorderedList<T>(); //索引無效,返回空 if (!indexIsValid(startIndex)) return resultList.iterator(); boolean[] visited = new boolean[maxCount]; //把全部頂點設爲false,白色 for (int i = 0; i < maxCount; i++) visited[i] = false; //進入隊列的爲true,即訪問過的,灰色 traversalQueue.enqueue(startIndex); visited[startIndex] = true; while (!traversalQueue.isEmpty()) { //出隊列塗黑存入resultList中 x = traversalQueue.dequeue(); resultList.addToRear((T) nodelist.get(x).getElement()); //若是進入resultList的頂點還有相鄰的未訪問過的頂點,將其塗灰入隊 for (int i = 0; i < maxCount; i++) { if (hasEdge(x, i) && !visited[i]) { traversalQueue.enqueue(i); visited[i] = true; Int++; } } } return new GraphIterator(resultList.iterator()); }
//最短路徑的頂點集 private Iterator<T> iteratorShortestPath(int startIndex, int targetIndex) { UnorderedListADT<T> resultList = new ArrayUnorderedList<T>(); //若是索引值都無效,返回空 if (!indexIsValid(startIndex) || !indexIsValid(targetIndex)) return resultList.iterator(); //it表示構成startindex和targetindex之間最短路徑的頂點集,並存儲在resultlist鏈表中,獲取結點集合的迭代器對象 Iterator<Integer> it = iteratorShortestPathIndices(startIndex, targetIndex); while (it.hasNext()) resultList.addToRear((T)nodelist.get(((Integer)it.next())).getElement()); return new GraphIterator(resultList.iterator()); }
//找到最短路徑的頂點值 private Iterator<Integer> iteratorShortestPathIndices(int startIndex, int targetIndex) { int index = startIndex; int[] pathLength = new int[maxCount];//路徑長度數組 int[] predecessor = new int[maxCount];//前驅結點 QueueADT<Integer> traversalQueue = new LinkedQueue<Integer>(); UnorderedListADT<Integer> resultList = new ArrayUnorderedList<Integer>(); //若是索引無效或起始終點爲同一索引,返回空 if (!indexIsValid(startIndex) || !indexIsValid(targetIndex) || (startIndex == targetIndex)) return resultList.iterator(); boolean[] visited = new boolean[maxCount];//訪問過爲true,染灰 //先標記爲都沒訪問過,染白 for (int i = 0; i < maxCount; i++) visited[i] = false; //將起始值入隊標爲訪問過,染灰 traversalQueue.enqueue(Integer.valueOf(startIndex)); visited[startIndex] = true; pathLength[startIndex] = 0;//路徑長度爲0 predecessor[startIndex] = -1;//前驅結點爲-1位置 //若是還有訪問過的灰色,而且未找到目標索引 while (!traversalQueue.isEmpty() && (index != targetIndex)) { index = (traversalQueue.dequeue()).intValue();//出隊列染黑,index儲存其元素值 //若是有其餘結點與index有聯繫卻沒有被訪問過的,入隊染灰 for (int i = 0; i < maxCount; i++) { if (hasEdge(index,i) && !visited[i]) { pathLength[i] = pathLength[index] + 1;//長度加一 predecessor[i] = index;//index爲其前驅結點,predecessor中存儲最短路徑頂點 traversalQueue.enqueue(Integer.valueOf(i));//進隊染灰 visited[i] = true; } } } //若是index不是目標索引,返回空 if (index != targetIndex) return resultList.iterator(); StackADT<Integer> stack = new LinkedStack<Integer>(); index = targetIndex; stack.push(Integer.valueOf(index));//目標索引入棧 do {//index不是起始索引值的元素值時,index表示其前驅結點的元素值,將結點的值依次入棧 index = predecessor[index]; stack.push(Integer.valueOf(index)); } while (index != startIndex); while (!stack.isEmpty()) resultList.addToRear(((Integer)stack.pop()));//棧不爲空時,彈出結點添加到resultlist鏈表 return new GraphIndexIterator(resultList.iterator());//resultlist中儲存的就是最短路徑的頂點集 }
程序中無意的對象引用保持,使得沒有明確的釋放對象,以至於堆增加再增加,直到沒有額外的空間。
網上的解決辦法:
選中被運行的類,點擊菜單‘run->run...’,選擇(x)=Argument標籤頁下的vm arguments框裏
輸入 -Xmx800m, 保存運行。
但我沒怎麼明白具體操做,我認爲個人錯誤多是第三種狀況,因而把第一週中inkedStack方法檢查了一下,發現方法size,isEmpty,和toString不完善,在其餘方法的條件中調用時就有可能出錯,修改以後問題解決。
無
譚鑫20172305:譚鑫的博客中最突出的就是他的擴展學習不少,好比Tarjan算法是我沒有了解的,能夠說很用心了,博客總結的一直很詳細,小小的建議就是但願解釋的時候能夠分一下層次,一大段一大段的有點難閱讀(o´ω`o)ノ
王禹涵20172323:王禹涵的博客總體很好,及哦啊才問題總結詳細,有一個問題就是不太明白代碼問題二。
關於圖的概念有邏輯性,容易理解,可是問題仍是在代碼理解上,我以爲Java學習不能停留在知識表面,要深刻理解代碼,並學會構造纔是最終目的。
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | |
---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 |
第一週 | 0/0 | 1/1 | 8/8 |
第二週 | 1163/1163 | 1/2 | 15/23 |
第三週 | 774/1937 | 1/3 | 12/50 |
第四周 | 3596/5569 | 2/5 | 12/62 |
第五週 | 3329/8898 | 2/7 | 12/74 |
第六週 | 4541/13439 | 3/10 | 12/86 |
第七週 | 1740/15179 | 1/11 | 12/97 |
第八週 | 5947/21126 | 1/12 | 12/109 |
第九周 | 7968/29094 | 2/14 | 12/121 |