20172327 2018-2019-1 《程序設計與數據結構》第五週學習總結

20172327 2018-2019-1 《程序設計與數據結構》第五週學習總結

教材學習內容總結

第九章 排序與查找

查找


1.查找:在某個項目組中找到指定元素或判斷是否存在。該項目組被稱爲查找池。

2.常見查找方式,線性查找。

3.查找目標:高效地完成查找,用最小化比較操做。一般查找池中項目數目定義了該問題的大小。

4.靜態方法(類方法):可經過類名激活

5.在方法聲明中,經過static修飾符就能夠把它聲明爲靜態的。

6.泛型方法:與泛型類類似,不是建立引用泛型參數的類,而是建立一個引用泛型的方法。

7.線性查找:從表頭開始依次比較每一個值,直到找到該目標元素。

8.二分查找將利用查池已經是排序的這一事實,每次比較都會刪除一半的可行候選項。

9.線性查找時間複雜度是O(n),二分查找時間複雜度爲log2n,因此n值較大時,二分查找要快的多。

排序


1.排序:基於某一標準,升序或者降序將某一組項目按照某個規定順序排列。

2.基於效率排序算法一般也分爲兩類:順序排序(使用一個嵌套循環對n個元素排序,大約有N^2次比較),對數排序(對n個元素進行排序,一般大約須要nlog2n次)

3.順序排序:選擇排序,插入排序,冒泡排序

4.對數排序:快速排序,歸併排序


5.選擇排序法:html

  • 初始時在序列中找到最小(大)元素,放到序列的起始位置做爲已排序序列;而後,再從剩餘未排序元素中繼續尋找最小(大)元素,放到已排序序列的末尾。以此類推,直到全部元素均排序完畢。
  • selectionSort方法實現兩個循環,外層循環控制下一個最小值存儲在那個位置,內層循環經過掃描全部大於等於外層循環指定索引的位置來找出剩餘列表的最小值。git

  • 序列{ 8, 5, 2, 6, 9, 3, 1, 4, 0, 7 }進行選擇排序的實現過程: 程序員

  • 宏觀圖: 算法


6.插入排序法:數組

  • 插入排序在實現上,一般採用in-place排序(即只需用到O(1)的額外空間的排序),於是在從後向前掃描過程當中,須要反覆把已排序元素逐步向後挪位,爲最新元素提供插入空間。
  • insertionSort方法使用了兩個循環來對某個對象數組進行排序,外層循環控制下一個插入值在數組中的索引,內層循環將前插入值和儲存在更小索引處的值進行比較。
  • 插入排序算法運做以下:
    1.從第一個元素開始,該元素能夠認爲已經被排序
    2.取出下一個元素,在已經排序的元素序列中從後向前掃描
    3.若是該元素(已排序)大於新元素,將該元素移到下一位置
    4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置
    5.將新元素插入到該位置後
    6.重複步驟2~5
  • 序列{ 6, 5, 3, 1, 8, 7, 2, 4 }進行插入排序的實現過程以下: 數據結構

  • 宏觀圖: 學習


7.冒泡排序法:ui

  • 它重複地走訪過要排序的元素,依次比較相鄰兩個元素,若是他們的順序錯誤就把他們調換過來,直到沒有元素再須要交換,排序完成。這個算法的名字由來是由於越小(或越大)的元素會經由交換慢慢「浮」到數列的頂端。
  • bubbleSort方法中的外層for循環表示n-1輪數據遍歷,內層for循環將從頭到尾掃描該數據,對相鄰數據進行成對比較,若是必要將其交換。
  • 冒泡排序算法的運做以下:
    1.比較相鄰的元素,若是前一個比後一個大,就把它們兩個調換位置。
    2.對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對。這步作完後,最後的元素會是最大的數。
    3.針對全部的元素重複以上的步驟,除了最後一個。
    4.持續每次對愈來愈少的元素重複上面的步驟,直到沒有任何一對數字須要比較。
    序列{ 6, 5, 3, 1, 8, 7, 2, 4 }進行冒泡排序的實現過程以下:

宏觀: .net


8.快速排序法:設計

  • 快速排序算法經過將列表分區,而後對這兩個分區進行遞歸式排序,從而完成對整個列表的排序。
  • quicksort方法很是依賴partition方法,起初用其將排序區域分開。partition方法的兩個內層while循環用於尋找位於錯誤分區的交換元素。第一個循環從左邊掃描到右邊,以尋找大於分區元素的元素,第二個循環從右邊掃描到左邊,以尋找小於分區元素的元素。
  • 快速排序算法的運做過程:
    1.從序列中挑出個一元素,做爲"基準"(pivot).
    2.把全部比基準值小的元素放在基準前面,全部比基準值大的元素放在基準的後面(相同的數能夠到任一邊),這個稱爲分區(partition)操做。
    3.對每一個分區遞歸地進行步驟1~2,遞歸的結束條件是序列的大小是0或1,這時總體已經被排好序了。
    序列:{ 1, 3, 4, 2, 8, 9, 8, 7, 5},基準元素是5,一次劃分操做後5要和第一個8進行交換,從而改變了兩個元素8
    的相對次序。
    宏觀:


9.歸併排序法:

  • 歸併排序算法經過將列表遞歸式分紅兩半直至每一個子列表都含有一個元素,而後將這些子列表歸併到一個排序順序中,從而完成對列表的排序。
  • 歸併排序的實現分爲遞歸實現與非遞歸(迭代)實現。遞歸實現的歸併排序是算法設計中分治策略的典型應用,咱們將一個大問題分割成小問題分別解決,而後用全部小問題的答案來解決整個大問題。非遞歸(迭代)實現的歸併排序首先進行是兩兩歸併,而後四四歸併,而後是八八歸併,一直下去直到歸併了整個數組。
  • 歸併排序法運做以下:
    1.申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列
    2.設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置
    3.比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置
    4.重複步驟3直到某一指針到達序列尾
    5.將另外一序列剩下的全部元素直接複製到合併序列尾
    序列{ 6, 5, 3, 1, 8, 7, 2, 4 }進行歸併排序的實例以下:

宏觀:

基數排序法


1.將全部待比較數值(正整數)統一爲一樣的數位長度,數位較短的數前面補零. 而後, 從最低位開始, 依次進行一次排序.這樣從最低位排序一直到最高位排序完成之後, 數列就變成一個有序序列.

2.若是咱們的無序是 T = [ 2314, 5428, 373, 2222, 17 ],那麼其排序的過程就以下兩幅所示。
基數排序過程圖-1 :

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

  • 問題1:在靜態方法那一節,有一個實例變量,我不太瞭解這是什麼意思?
  • 問題解決和分析:實例變量:在類的聲明中,屬性是用變量來表示的。這種變量就稱爲實例變量,是在類聲明的內部,但在類的其餘成員方法以外聲明的。類的每一個對象維護它本身的一份實例變量的副本。

  • 問題2:@SuppressWarnings是啥,怎麼用。
  • 問題解決和分析:
    1.指示應該在註釋元素(以及包含在該註釋元素中的全部程序元素)中取消顯示指定的編譯器警告。注意,在給定元素中取消顯示的警告集是全部包含元素中取消顯示的警告的超集。例如,若是註釋一個類來取消顯示某個警告,同時註釋一個方法來取消顯示另外一個警告,那麼將在此方法中同時取消顯示這兩個警告。
    2.根據風格不一樣,程序員應該始終在最裏層的嵌套元素上使用此註釋,在那裏使用纔有效。若是要在特定的方法中取消顯示某個警告,則應該註釋該方法而不是註釋它的類。

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

  • 問題1:在實現pp9.3sorting類改編時,我對於歸併排序和快速排序的循環次數的計算感受到很迷茫,我不知道該如何計算。

  • 解決分析:
    經過對同窗方法的研究,我以爲有兩種方法能夠解決,一種是直接
public static <T extends Comparable<T>>
    void mergeSort(T[] data)
    {
        times = times2 = 0;
        long startTime=System.nanoTime();
        mergeSort(data, 0, data.length - 1);
        long endTime = System.nanoTime();
        long temp = times + times2;
        System.out.println("程序運行時間:" + (endTime - startTime) + "ns");
        System.out.println("比較次數爲:"+ temp);
    }

    private static int times;
    private static <T extends Comparable<T>>
    void mergeSort(T[] data, int min, int max)
    {
        if (min < max)
        {
            times++;
            int mid = (min + max) / 2;
            mergeSort(data, min, mid);
            mergeSort(data, mid+1, max);
            merge(data, min, mid, max);
        }

    }

經過引入times,來在循環中經過計算最後times相加的和。
還有一種是:

public static <T extends Comparable<T>>
    void mergeSort(T[] data)
    {
        int count=0;
        long startTime = System.nanoTime();//獲取開始的時間;
        count = mergeSort(data, 0, data.length - 1);
        long endTime = System.nanoTime();//獲取結束的時間;
        System.out.println("程序所需時間:"+ (endTime - startTime) + "ns");
        System.out.println("比較次數:"+ count);
    }
    

    private static <T extends Comparable<T>>
        int mergeSort(T[] data, int min, int max)
    {
        int count = 0;
        if (min < max)
        {
            int mid = (min + max) / 2;
            mergeSort(data, min, mid);
            mergeSort(data, mid+1, max);
            merge(data, min, mid, max);
        }
        return count;
    }

經過對下邊類改爲有返回值的類,將count返回。

代碼託管

結對及互評

正確使用Markdown語法(加1分)
模板中的要素齊全(加1分)
教材學習中的問題和解決過程, (加3分)
代碼調試中的問題和解決過程, 無問題
感想,體會真切的(加1分)
點評認真,能指出博客和代碼中的問題的(加1分)

  • 20172317
    基於評分標準,我給以上博客打分:2分。得分狀況以下:
  • 20172320
    基於評分標準,我給以上博客打分:8分。得分狀況以下:

    • 結對學習內容
      • 教材第9章,運行教材上的代碼
      • 完成課後自測題,並參考答案學習
      • 完成課後自測題,並參考答案學習
      • 完成程序設計項目:至少完成PP9.二、PP9.3

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

這周將排序全學了一遍,感受有些理解起來還好,寫起來也還算好些,可是有些知道它運行的流程但代碼實現作不到,這就讓人很着急。我還會再看看代碼,將二分法實現的歸併排序,快速排序以及基數排序再多研究一下,把不懂的搞懂。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/0 1/1 8/8
第二週 1306/1306 1/2 20/28
第三週 1291/2597 1/3 18/46
第四周 4361/6958 2/5 20/66
第五週 1755/8713 1/6 20/86

參考:軟件工程軟件的估計爲何這麼難軟件工程 估計方法

  • 計劃學習時間:10小時

  • 實際學習時間:8小時

  • 改進狀況:

(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表
)

參考資料

相關文章
相關標籤/搜索