1. 程式人生 > ># 20172333 2018-2019-1 《程式設計與資料結構》第八週學習總結

# 20172333 2018-2019-1 《程式設計與資料結構》第八週學習總結

20172333 2018-2019-1 《程式設計與資料結構》第八週學習總結

教材學習內容總結

《Java軟體結構與資料結構》第十二章-優先佇列與棧

一、堆

  • ①堆是一顆具有兩個附加屬性的完全二叉樹
    • 附加屬性:1.堆是一顆完全樹。2.對於每個結點,它小於或等於其左孩子和右孩子。
  • ②堆預設為最小堆,當然也有最大堆。
  • 圖堆12
操作 說明
addElement 將給定元素新增到該堆中
removeMin 刪除堆的最小元素
findMin 返回一個指向堆中最小元素的引用
public interface HeapADT<T> extends BinaryTreeADT<T> 
{
   /** 
    * Adds the specified object to this heap. 
    *
    * @param obj the element to be added to the heap
    */   
   public void addElement(T obj);
   
   /** 
    * Removes element with the lowest value from this heap. 
    *
    * @return the element with the lowest value from the heap
    */
   public T removeMin();
   
   /** 
    * Returns a reference to the element with the lowest value in 
    * this heap. 
    *
    * @return a reference to the element with the lowest value in the heap
    */
   public T findMin();
}
  • ③addeEement方法:
    • 該方法將Conparable元素新增到棧的恰當位置,維持該堆的完全性屬性與有序屬性。
    • 插入的新節點只有一個正確的位置,即最後一層的左邊下一個位置,要麼是最後一層再加一層左邊的第1個位置。插入點一般是最後一片葉子的結點。
    • 實現:

public void add(T newEntry) {
        lastIndex++;
        if(lastIndex >= heap.length)
            doubleArray();
        int newIndex = lastIndex;
        int parentIndex = newIndex / 2;
        heap[0] = newEntry;
        while(newEntry.compareTo(heap[parentIndex]) > 0){
            heap[newIndex] = heap[parentIndex];
            newIndex = parentIndex;
            parentIndex = newIndex / 2;
        }
        heap[newIndex] = newEntry;
    }
  • ④RemoveMin方法
    • 在最小堆裡面,最小的元素是堆的根,我們需要刪除並且返回它的話,需要一個新的根,通常這個新根是最末的一個葉節點。
    • 由於通常新根變為根節點後堆就不成立了,需要對其進行平衡。
  • ⑤findMin方法
    • 最小堆的根就是最小元素,直接返回根即可。
    • 程式碼實現
public T findMin() throws EmptyCollectionException
    {
        if (isEmpty())
            throw new EmptyCollectionException("ArrayBinaryTree");

        return tree[0];
    }

二、用連結串列實現堆

  • ①由於在插入元素後,要進行排序,所以堆中的結點需要擁有指向父輩的指標。
  • ②實現過程中依舊是addElement、removeMin、findMin三種方法,且書上已經有了程式碼就不多贅述。
  • ③但是需要注意的是在addelement中使用了兩個私有方法,一個是getNextParentAdd的方法,它用於返回指向一個結點的引用,一般適用於每個結點指向父輩的。另外一個方法是heapifyAdd這個新增後的排序。
  • ④相對的刪除過程中也有兩個私有方法,一個為追蹤最後一個葉子的方法,一個則是用於對刪除後的堆進行排序。

三、用陣列實現堆

  • ①陣列的實現堆的方法比連結串列更加簡潔。因為連結串列需要隨時追蹤父輩結點和最後一個葉子結點,但是陣列不同,陣列的最後一位就一定會是葉子結點。
  • ②雖然在addelemnt中沒有了追蹤父輩的方法,但是作為陣列,它的容量是恆定的,一旦出現新增的情況,就需要考慮擴容,所以依舊是兩個方法,一個擴容,一個用來重排序。
  • ③連結串列與陣列的新增方法的複雜度相同,與此相對的是的刪除方法的複雜度也是相同的。

教材學習中的問題和解決過程

  • 問題1:堆是否和紅黑樹一樣,一旦進行新增刪除就需要進行平衡?
  • 回答1:堆新增刪除元素可能符合原本的堆的性質,可以不進行重排序就可以實現堆。
  • 問題2:為什麼說最小堆實現了高效的優先順序佇列?
  • 回答2:由於佇列的性質既是先進先出,我們只需要對Conparable定義為先對於優先順序進行比較即可實現優先順序佇列。

程式碼除錯中的問題和解決過程

  • 本次書上PP問題主要在書上已經是基本實現了的,所以這周的程式碼問題主要是出現在本次實驗過程中。
  • 第二次實驗部落格

程式碼託管

-圖程式碼

上週考試錯題總結

結對及互評

基於評分標準,我給李楠的部落格打分:7分。得分情況如下:

正確使用Markdown語法(加1分)

模板中的要素齊全(加1分)

教材學習中的問題和解決過程, (加3分)

程式碼除錯中的問題和解決過程, 無問題

感想,體會真切的(加1分)

點評認真,能指出部落格和程式碼中的問題的(加1分)

點評過的同學部落格和程式碼

  • 本週結對學習情況

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

學習進度條

程式碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/0 1/1 10/10
第二週 0/0 1/2 10/20
第三週 1500/1500 1/3 10/30
第四周 2761/4261 2/5 25/55
第五週 814/5075 1/6 15/70
第六週 1091/6166 1/7 15/85
第七週 1118/7284 1/8 15/100
第八週 1235/8519 2/10 15/115