2017-2018-20172309 《程序設計與數據結構》第八週學習總結

2017-2018-20172309 《程序設計與數據結構》第八週學習總結

1、教材學習內容總結

相信其它不少同窗都是以小頂堆來介紹這一章內容,因此我將以大頂堆來介紹這章內容。html

1.1 堆的簡單介紹:

  • 堆的定義:(大頂堆
    • 堆其實是一棵徹底二叉樹。
    • 堆知足兩個性質:
      1. 堆的每個父節點都大於其子節點;
      2. 堆的每一個左子樹和右子樹也是一個堆。
  • 堆的分類:
    • 堆分爲兩類:
      1. 最大堆(大頂堆):堆的每一個父節點都大於其孩子節點;
      2. 最小堆(小頂堆):堆的每一個父節點都小於其孩子節點;
    • 例子:

  • 堆的操做:
    • 堆的定義是二叉樹的拓展,所以他也繼承了二叉樹的全部操做。
    • 操做列表(大頂堆爲例):
    操做 說明
    addElement() 將給定元素添加到該堆中去
    removeMax() 刪除堆中最大的元素
    findMax() 返回一個指向堆中最大元素的引用
  • addElement操做:
    • addElement方法將給定的Comparable元素添加到堆中的恰當位置,且維持該堆的徹底屬性和有序屬性。
    • 由於堆是一棵徹底二叉樹,所以對於新插入的節點而言,就只有一個正確的位置,要麼是h層左邊的下一個空位置,要麼是h+1層的第一個位置(此時h層已經裝滿了)。
    • 以下圖:它有這兩個位置可插入:
    • 一般在堆的實現中,咱們會對二叉樹的最後一片葉子進行跟蹤記錄。
    • 最大堆的插入:
  • removeElement操做:
    • 對於大頂堆而言,刪除最大元素即刪除二叉樹的根結點,若是刪除根結點而要想維持堆的徹底性,必須與最後一片葉子進行交換位置。
    • 交換位置後,必須進行重排序、以維持堆的第二個屬性:排序。
    • 用圖表示下過程:
  • findMax操做java

    findMax操做將返回一個指向該最大堆中最大元素的引用,也就是根結點的引用。因此實現這一操做只需返回儲存在根結點的元素便可。node

1.2使用堆:優先級隊列。

  • 咱們先來舉個例子來感覺下優先級隊列。
    • 生活中,排隊時講究女士優先。
    • 遊戲中,抽獎人民幣玩家得到好東西的機率更大!
  • 好,咱們如今來講什麼是優先級隊列:
    • 具備更高優先級的項目優先,好比女士、人民幣玩家。
    • 具備相同優先級的項目使用先進先出的方法 肯定其排序。
  • 雖然最大堆根本就不是一個隊列,可是他提供了一個高效的優先級隊列實現。
  • 關鍵代碼:git

    在我看來,這個比較的代碼是重中之重的。數組

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;
    }

1.3 用鏈表實現堆:

  • 由於咱們須要再插入元素後可以向上遍歷樹,所以結點中須要一個指向雙親結點的指針
public class HeapNode<T> extends BinaryTreeNode<T>
{
    public HeapNode<T> parent;//指向雙親的指針。

  
    public HeapNode(T obj) 
    {
        super(obj);
        parent = null;
    }
}
  • 咱們還須要一個可以跟蹤該堆最後一片葉子 的指針:數據結構

    public HespNode lastNode;函數

  • 最大堆的各類操做:
    • addElement操做:
      • addElement操做完成三個任務:
        1. 再恰當位置添加一個元素。
        2. 對堆進行重排序。
        3. 將lastNode指針從新指向新的最末結點。
      • addElement操做的時間複雜度爲:O(log n)
    • removeMax操做:
      • removeMax主要完成三個操做:
        1. 將最後一片葉子結點與根結點交換位置。
        2. 對堆進行重排序。
        3. 返回初始根元素。
      • removeMax操做的時間複雜度爲:O(log n)
    • findMax操做的時間複雜度爲O(log n)

1.4用數組實現堆:

  • 堆的儲存通常都是用數組實現的。
  • 堆是基於二叉樹實現的,在二叉樹的數組視線中,對於任一索引值爲n的結點,其左結點在2n+1的位置右結點在2n+2的位置
  • 用數組實現堆的操做與用鏈表實現堆的操做步驟同樣。但值得注意的是:鏈表實現和數組實現的addElement操做時間複雜度雖然都爲O(log n),,但實際上鍊表更快點。

1.5 使用堆:堆排序。

排序方法有兩個部分構成:添加列表的每一個元素、一次刪除一個元素。學習

堆排序的時間複雜度爲O(log n).測試

  • 進入實戰:還記得上次的一個實驗,給咱們一個數組沒讓咱們造成一個大頂堆,以後讓咱們排序:如今讓咱們整理一下思路:
    • 首先給出咱們一個數組:[45,36,18,53,72,30,48,93,15,35]
    • 而後咱們應該按照它們的索引造成一個二叉樹:
    • 而後重排序,獲得一個大頂堆:

    • 每輪排序的結果能夠這樣表達:
    public class test {
     public static void main(String[] args) {
         BigArraryHeap<Integer> temp=new BigArraryHeap<Integer>();
         int[] list={36,30,18,40,32,45,22,50};
         Object[] list2 = new Object[list.length];
    
         //將數組中的元素添加到大頂堆中
         for (int i = 0; i < list.length; i++)
             temp.addElement(list[i]);
    
         System.out.println("大頂堆的輸出結果爲:"+ temp);
         System.out.println();
    
         for(int n = 0; n < list2.length; n++){
             list2[n] = temp.removeMax();
             String result = "";
             for(int a = 0; a <= n; a++){
                 result += list2[a] + " ";
             }
             System.out.println("第" + (n+1) + "次排序:" + temp + " ~ " + result);
         }
    
         System.out.println();
    
         System.out.print("最後排序結果: ");
         String result = "";
         for(int m = 0; m < list.length; m++){
             result += list2[m] + " ";
         }
         System.out.println(result);
       }
     }
    • 運行結果爲:

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

  • 問題1:如何理解這段話,該怎樣實現?.net

    一般在堆的實現中,咱們會對二叉樹的最後一片葉子進行跟蹤記錄。

  • 問題1解決方案:

    就是在對堆進行刪除操做的時候須要將根結點與最後一片葉子結點進行交換位置,因此每一次操做都得更新lastNode結點。

  • 問題2:書上介紹了用數組實現的堆排序,那麼鏈表實現的堆排序應該怎樣排序?
  • 問題2解決方案:書上數組對對進行排序是寫了一個方法,當想要進行排序的時候直接調用這個方法就OK,而咱們選在在測試類裏面直接進行排序,使用最大堆,取出最大堆輸出,而後就能夠直接輸出。

    如圖:

  • 問題三:在網上搜尋有關於書上的資料室,出現了這麼一個尷尬場面:

    以後我點進去看了一下:

原來是講解了有關:棧內存和堆內存。
講了這麼個些東西,來潦草的總結下:

  • ava把內存劃分紅兩種:一種是棧內存,一種是堆內存
    在函數中定義的一些基本類型的變量和對象的引用變量都在函數的棧內存中分配。
  • 當在一段代碼塊定義一個變量時,Java就在棧中爲這個變量分配內存空間,當超過變量的做用域後,Java會自動釋放掉爲該變量所分配的內存空間,該內存空間能夠當即被另做他用。 - 堆內存用來存放由new建立的對象和數組。
  • 在堆中分配的內存,由Java虛擬機的自動垃圾回收器來管理。
  • 在堆中產生了一個數組或對象後,還能夠在棧中定義一個特殊的變量,讓棧中這個變量的取值等於數組或對象在堆內存中的首地址,棧中的這個變量就成了數組或對象的引用變量。
  • 引用變量就至關因而爲數組或對象起的一個名稱,之後就能夠在程序中使用棧中的引用變量來訪問堆中的數組或對象。
    (大概就看懂了這麼多)

代碼調試中的問題和解決過程

  • 問題1:如何用堆構建一個隊列、棧?
  • 問題1解決方案:

    首先咱們得知道咱們必須運用優先級堆,而且每一次添加元素,優先級都加一(從0開始)。

  • 而後咱們根據隊列、棧的特色來輸出
    • 隊列是一種先進先出的結構,因此咱們只要使用最小堆中的removeMin方法便可輸出最早進去的元素。
    • 棧是一種先進後出的結構,因此咱們只要使用最大堆中的removeMax方法便可輸出最後面進去的元素,由於它的優先級高,因此他在前面輸出。
    • 結果
  • 問題二:符合把一個Object型數據轉化爲char類型數據?
  • 原問題是這樣的我須要把Object operator= +轉化爲char型數據,可是若是直接轉,好比這樣(char)operator是會拋出CalssCastException錯誤的!
  • 以後解決辦法是先轉化成String 而後再轉化成char類型。
//像這樣:
String a = String.valueOf(ope.pop());//ope.pop()出來的是一個Object型數據。
           operator = a.charAt(0);

代碼之家

代碼託管

上週考試錯題總結

第十章錯題

  • 錯題1及緣由:

    What type does "compareTo" return?
    A .int
    B .String
    C .boolean
    D .char

    錯誤緣由:comparaTo方法返回的是 -1,0,1
    return "a".comparaTo("b")>0false or ture

    第十一章錯題

  • 第十二章錯題

    Since a heap is a binary search tree, there is only one correct location for the insertion of a new node, and that is either the next open position from the left at level h or the first position on the left at level h+1 if level h is full.
    A .True
    B .Flase

    錯誤緣由:堆是一棵徹底二叉樹、不是一顆二叉搜索樹。本身瞎了眼!!!!

點評模板:

博客或代碼中值得學習的或問題:

- 內容很詳細,把堆介紹的很透徹,
- 運用豐富的圖片表達思想、好比插入、刪除結點的介紹。
- 提出問題有點少。

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20172310
    • 結對學習內容
      • 第十二章內容:堆、優先級隊列
      • 實驗二:樹的綜合運用
  • 上週博客互評狀況
    - 20172302
    - 20172308
    - 20172310

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

這一章比起前面相對比較簡單,但本身不能鬆懈.哎,比較難受的是這兩天的假期都要貢獻給博客了~~~~~o(╥﹏╥)o

學習進度條(上學期截止7200)

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 260/0 1/1 05/05
第二週 300/560 1/2 13/18
第三週 212/772 1/4 21/39
第四周 330/1112 2/7 21/60
第五週 1321/2433 1/8 30/90
第六週 1024/3457 1/9 20/110
第七週 1024/3457 1/9 20/130
第八週 643/4100 2/11 30/170

參考資料

1.優先隊列
2.堆排序
3.java 各類數據類型之間的轉化
4.java中的棧與堆

相關文章
相關標籤/搜索