20172304《程序設計與數據結構》第八週學習總結

20172304 《程序設計與數據結構》第八週學習總結

教材學習內容總結

本週主要學習的內容是堆。堆是二叉樹的擴展
什麼是堆
堆就是具有兩個附加屬性的一棵二叉樹
1.它是一棵完全樹。
2.對每一結點,他小於或等於其左孩子和右孩子(最小堆)最大堆與最小堆相反。
堆的操作

操作 說明
addElement 將給定元素添加到該堆中
removeMin 刪除堆的最小元素
findMin 返回一個指向堆中最小元素的引用

addElement操作
方法將給定的元素添加到堆中恰當的位置處,且維持該堆的完全性屬性和有序屬性。如果給定的元素鄙視Comparable的,則該方法將拋出一個ClassCastException異常。
至於他一開始進行的插入的原則類似於層序遍歷的順序。如果新結點小於其雙親則將它們互換。我們沿着樹向上繼續這一過程,直至該心智要麼是大於其雙親要麼是位於該堆的根處。通常我們會對最末一片葉子結點進行跟蹤。
堆的插入點(圖中虛線部分)


堆的插入和重排序



removeMin操作
removeMin操作將刪除最小堆中的最小元素並返回它。而一旦根結點被刪除,那麼就要使用最後一片葉子結點來代替它。然後對整個堆進行重排序,使其符合堆的性質。具體實現方法爲將該新根的元素與其較小的孩子進行比較,且如果孩子更小則將它們交換,沿着樹鄉下繼續這一過程,直至該元素要麼位於某一葉子結點中,要麼比它的兩個孩子都小。
堆中最末一片葉子的例子(顏色爲黃色的部分)



堆的刪除和重排序


findMin操作
findMin方法將返回一個指向該最小堆中最小元素的引用。由於該元素總是被儲存在該樹的根處,所以事先這一方法只需通過返回儲存在在根處的元素即可。
使用堆:優先級隊列
用鏈表實現堆
用數組實現堆

教材學習中遇見的問題

問題:在看教材代碼時看到用堆實現優先級隊列時突然矇住了,不懂得是什麼意思。
解答:後來經過了多次的思考以及結合教材上的解讀,終於捋清了,教材上提供了兩個類一個是PrioritizedObject類,一個是PriorityQueue類。前面那個類可以近似看成是結點類,定義了要輸入對象的優先級,輸入的次序以及儲存的方法等。這些都不是最重要的,最重要的是它重寫了一個compareTo方法,通過將自身的優先級與傳入的對象的優先級進行比較來返回正負值。如果優先級相同,就對階進行比較。一開始我不懂的是第二個類中的幾行代碼。

 public void addElement(T object, int priority) 
    {
        PrioritizedObject<T> obj = new PrioritizedObject<T>(object, priority);
        super.addElement(obj);
    }

注:第二個類繼承了ArrayHeap類
一開始我不理解的是既然構造函數聲明瞭兩個變量,而且在ArrayHeap類中的Comparable實例化的對象可以對任何數據進行比較大小,爲什麼object不會干預到正常的比較呢?
後來我在ArrayHeap中看見了這樣的代碼

(Comparable)tree[left]).compareTo(tree[right]) < 0

以及在PriorityQueue類的頭中看見了這樣的代碼

ArrayHeap<PrioritizedObject<T>>

再聯想到在PrioritizedObject中重寫的comapreTo方法

 public int compareTo(PrioritizedObject obj) 
    {
      int result;
                
      if (priority > obj.getPriority())
          result = 1;
      else if (priority < obj.getPriority())
          result = -1;
      else if (arrivalOrder > obj.getArrivalOrder())
          result = 1;
      else
          result = -1;
      
      return result;
    }

就知道了在第二個類中引用的ArraryHeap類中定義的是第一個類,所以在進行Comparable是使用的實際上是在第一個類中重寫的copareTo方法。即先按照優先級進行排序然後在按照先進先出的順序進行排序。

代碼調試中的問題和解決方案

問題:在進行pp12.1時,出現了異常

解答:後來發現是在改代碼時忽略了圖中第十行代碼在Comparable後面的方括號中沒有將原來的PrioritizedObject改爲PrioritizedObject1,所以出現了類型無法轉換的錯誤。

代碼託管

(statistics.sh腳本的運行結果截圖)

上週考試錯題總結

博客互評

20172304郭愷郭愷同學能對教材的內容進行合理的總結又能將樹中不懂得知識點分析的如此淋漓盡致。
20172328李馨雨李馨雨同學的博客內容充實,排版美觀,條理清晰,是不可多得的博客。

點評過的同學博客和代碼

  • 上週博客互評情況
    20172304郭愷郭愷同學的博客依然是一如既往的優秀,既將教材中的內容總結的詳略得當,還能具體而全面的對自己的錯誤進行總結和提升。
    20172328李馨雨李馨雨同學的博客還是很認真的。

    其他(感悟、思考等,可選)

    本週學習了堆的相關知識,堆是建立在二叉樹基礎上的一種數據結構,所以實現和理解起來比較容易。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 30/30 1/1 10/10
第二週 766/796 1/2 40/50
第三週 817/1613 1/3 20/70
第四周 1370/3983 2/5 30/100
第五週 1235/5214 1/6 10/110
第六週 1328/6542 1/7 20/130
第七週 1218/7860 1/8 20/150
第八週 585/9445 1/9 20/170

參考資料

1.藍墨雲班課
2.java軟件結構與數據結構

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章