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

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

教材學習內容總結

本章名稱 《排序與查找》

  • 若是要實現查找到某一對象,就必須可以將一個對象與另外一個對象進行比較,故咱們須要對全部涉及的元素實現Comparable接口,可是Comparable接口中的compareTo方法能夠由咱們根據本身的需求進行重寫。

    這是Java API中的Comparable接口,它存在於java.lang包中。而最終對比的結果大於時返回正整數,等於時返回零,小於時返回負整數。html

  • 靜態方法:使用static修飾符修飾方法,可使得在調用該方法時不用實例化方法。而靜態方法和實例方法的區別主要體如今兩個方面,一、在外部調用靜態方法時,可使用"類名.方法名"的方式,也可使用"對象名.方法名"的方式。而實例方法只有後面這種方式。也就是說,調用靜態方法能夠無需建立對象。二、靜態方法在訪問本類的成員時,只容許訪問靜態成員(即靜態成員變量和靜態方法),而不容許訪問實例成員變量和實例方法;實例方法則無此限制。java

  • 泛型方法:泛型方法的使用能夠在調用的時候指明類型,更加靈活。圖例:
    • 定義泛型方法:git

    • 調用泛型方法:算法

查找

  • 線性查找法:一個很是簡單的查找方式,從開頭或結尾開始查找目標,將每一個元素的特徵值與查找目標的特徵值做比較,最終得出結果。可是在最壞的狀況中會遍歷整個列表才能查找到該元素。該方法不要求列表是否排序。他的圖示以下:編程

  • 二分查找法:從已排序列表的中間開始查找元素,若是沒有找到則繼續查找,由於列表已排序,故咱們就能夠僅從列表的一邊開始查找下一個元素,由於它一定位於列表的前半部分和後半部分,被咱們查找的那一部分被稱爲可行候選項,圖示:數組

    • 具體的代碼實現可使用遞歸方法:直接或間接調用本身的算法。例子以下:
    public static <T extends Comparable<T>>  
        boolean binarySearch(T[] data, int min, int max, T target)
    {  
        boolean found = false;
        int midpoint = (min + max) / 2;  // determine the midpoint
    
        if (data[midpoint].compareTo(target) == 0) {
            found = true;
        } else if (data[midpoint].compareTo(target) > 0)
        {
            if (min <= midpoint - 1) {
                found = binarySearch(data, min, midpoint - 1, target);
            }
        }
    
        else if (midpoint + 1 <= max) {
            found = binarySearch(data, midpoint + 1, max, target);
        }
    
        return found;
    }

    binarySearch方法中直接調用本身,以便實現二分查找。數據結構

排序

基於效率的排序算法與查找相似一般分爲兩類:順序查找和對數查找,順序查找一般使用一對嵌套循環對n個元素排序,大約須要n2次比較,而對數查找大約須要nlog2n次比較。本章中主要涉及五中排序算法,其中順序排序三種:選擇排序、插入排序、冒泡排序,對數排序兩種:快速排序、歸併排序。學習

  • 選擇排序法:首先找出整個列表的最小值與該列表的第一個位置的值進行交換,第二輪掃描除了第一個位置之外的最小值與第二個位置的值進行交換,直至排序完成。圖示:優化

  • 插入排序法:先行比較前面兩個元素,若有必要就交換順序,以後掃描後面的元素,將後面的元素插入到前兩個元素的應有位置,而且前兩個元素也相應的移動。如此往復直至將最後一個元素插入到該有的位置,排序完成。圖示:ui

  • 冒泡排序法:從第一個元素開始掃描列表並比較相鄰的兩個元素,按照排序規定選擇是否交換位置,直至將最大值「冒泡」至列表的尾端,至此完成一個元素的排序,第二再次掃描列表找到剩下的最大的元素,一路「冒泡」到倒數第二個位置。如此往復,直至排序完成。圖示:

  • 快速排序法:原理,選擇一個關鍵值做爲基準值。比基準值小的都在左邊序列(通常是無序的),比基準值大的都在右邊(通常是無序的)。通常選擇序列的第一個元素。一次循環:從後往前比較,用基準值和最後一個值比較,若是比基準值小的交換位置,若是沒有繼續比較下一個,直到找到第一個比基準值小的值才交換。找到這個值以後,又從前日後開始比較,若是有比基準值大的,交換位置,若是沒有繼續比較下一個,直到找到第一個比基準值大的值才交換。直到從前日後的比較索引>從後往前比較的索引,結束第一次循環,此時,對於基準值來講,左右兩邊就是有序的了。圖示:

  • 歸併排序法:其算法是將多個有序數據表合併成一個有序數據表。若是參與合併的只有兩個有序表,則成爲二路合併。對於一個原始的待排序數列,每每能夠經過分割的方法來歸結爲多路合併排序。圖示:

各類排序算法的比較:

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

  • 問題一:爲何對數排序一般須要nlog2n比較呢?
  • 問題一解決方案:在網上查閱資料,
    • 對於歸併排序法,考慮元素比較次數,兩個長度分別爲m和n的有序數組,每次比較處理一個元素,於是合併的最多比較次數爲(m+n-1),最少比較次數爲min(m,n)。對於兩路歸併,序列都是兩兩合併的。不妨假設元素個數爲n=2^h,第一次歸併:合併兩個長度爲1的數組,總共有n/2個合併,比較次數爲n/2。第二次歸併:合併兩個長度爲2的數組,最少比較次數是2,最可能是3,總共有n/4次,比較次數是(2~3)n/4。第三次歸併:合併兩個長度爲4的數組,最少比較次數是4,最可能是7,總共有n/8次合併,比較次數是(4-7)n/8。第k次歸併:合併兩個長度爲2^(k-1)的數組,最少比較次數是2^(k-1),最可能是2^k-1,總共合併n/(2^k)次,比較次數是2^(k-1)~(2^k-1)=n/2~n(1-1/2^k)。按照這樣的思路,能夠估算比較次數下界爲n/2*h=nlog2(n)/2。上界爲n[h-(1/2+1/4+1/8+...+1/2^h)]=n[h-(1-1/2^h)]=nlog2(n)-n+1。綜上所述,歸併排序比較次數爲nlog2(n)/2~nlog2(n)-n+1。
    • 對於快速排序法,理想狀況下,快速排序每次劃分都將原始序列劃分爲兩個等長的子序列。因此其比較次數爲T(n)=2T(n/2)+n,因此其平均指望時間爲nlog(n)。但在最壞狀況下,即序列有序情形下,每次劃分只能分出一個元素,於是總共須要(n-1)次劃分,總的比較次數爲(n-1)+(n-2)+...+1=n(n-1)/2,即退化爲O(n^2).
  • 問題二:對於歸併排序法的理解不足,雖然看到書上的例子,可是應該如何去實現,在分解事後的合併排序又是如何實現?
  • 問題二解決方案:查閱資料得知,歸併排序是將兩個或兩個以上的有序序列合併成一個新的有序序列。本篇文章介紹的就是歸併排序主要是將兩個有序數據序列合併成一個新的有序序列。

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

  • 問題一:在寫PP9.3時的selectionSort方法時,次數輸出爲零,如圖:

問題代碼以下:

  • 問題一解決:修改frequency變量位置如圖:

修改後效果圖以下:

代碼託管「點這裏跳轉到碼雲」

上週考試錯題總結

  • 錯題一:

  • 解析:書上原話,

    Java集合API中含有索引列表的三種實現。

結對及互評

  • 博客中值得學習的或問題:
    • 範雯琪同窗的博客課本上的學習內容總結部分寫得十分詳細,值得學習。因此這周我也去學習了一番,在課程學習中圖文並茂。
  • 代碼中值得學習的或問題:
    • commit提交的解釋清晰明瞭,我以爲我應該學習。因此我也學習了部分,細化了commit提交。

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20172303

    • 結對學習內容
      • 給她講解了ASL的算法問題。
      • 在她的指導下個人博客有了質的飛躍,從量變到質變。

其餘

  • 感悟:排序的方法如此之多,每一個排序法對須要排序的元素的多少而使用的時間各不相同,在以後的編程中,應該多多想到算法的問題以及複雜度的問題,而不是簡單的將做業作出,應該多去想一想優化的問題。

課本單詞

(本部分用於收集本章節後的生詞)

  • binary search:二分查找
  • bubble sort:冒泡排序
  • class method:類方法
  • generic method:泛型方法
  • insertion sort:插入排序
  • linear search:線性查找
  • logarithmic algorithm:對數算法
  • logarithmic sort:對數排序
  • merge sort:歸併排序
  • partition:分區
  • partition element:分區元素
  • quick sort:快速排序
  • radix sort:基數排序
  • searching:查找
  • search pool:查找池
  • selection sort:選擇排序
  • sequential sort:順序排序
  • target element:目標元素
  • viable candidates:可行候選

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/5000 2/2 8/8 認真學習!積極向上
第二週 812/812 1/3 22/30
第三週 814/1626 1/4 20/50
第四周 1386/3012 2/6 20/70 愉快的國慶節就要結束了...
第五週 1222/3234 1/7 30/100
  • 計劃學習時間:25小時

  • 實際學習時間:30小時

  • 改進狀況:在博客中圖文並茂,commit提交改進。

參考資料

相關文章
相關標籤/搜索