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

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

教材學習總結

第一章

  • 軟件的質量特徵
    • 正確性:軟件可否有效處理問題
    • 可靠性:軟件發生故障的頻率
    • 健壯性:軟件修復錯誤以及bug出現的頻率
    • 可用性:軟件處理問題效率
    • 可維護性:代碼的整潔規範是否有利於維護
    • 可重用性:使用已有的組件來減小開發工做量
    • 可移植性:能在不一樣開發環境下能順利運行
    • 運行效率:提升軟件運行效率,優化CPU時間和內存
  • 數據結構
    數據結構是計算機存儲、組織數據的方式。程序員

  • 算法效率
    算法效率是指算法執行的時間,算法執行時間需經過依據該 算法編制的程序在計算機上運行時所消耗的時間來度量。算法

第二章

  • 增加函數:表示問題(n)大小與咱們但願最優化的值之間的關係。
  • 算法複雜度: 時間複雜度是指執行算法所須要的計算工做量;
    而空間複雜度是指執行這個算法所須要的內存空間。
    (算法的複雜性體如今運行該算法時的計算機所需資源的多少上,計算機資源最重要的是時間和空間(即寄存器)資源,所以複雜度分爲時間和空間複雜度)
  • 漸進複雜度稱爲算法的階次。
  • 大O記法:經常使用大O表示法表示時間複雜性,注意它是某一個算法的時間複雜性。大O表示只是說有上界,由定義若是f(n)=O(n),那顯然成立f(n)=O(n^2),它給你一個上界,但並非上確界,但人們在表示的時候通常都習慣表示前者。此外,一個問題自己也有它的複雜性,若是某個算法的複雜性到達了這個問題複雜性的下界,那就稱這樣的算法是最佳算法。

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

  • 問題1:散列表是何?
  • 問題解決:
    • 哈希表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫作散列函數,存放記錄的數組叫作散列表。
      記錄的存儲位置=f(關鍵字)
      這裏的對應關係f稱爲散列函數,又稱爲哈希(Hash函數),採用散列技術將記錄存儲在一塊連續的存儲空間中,這塊連續存儲空間稱爲散列表或哈希表(Hash table)。編程

    • 哈希表hashtable(key,value) 就是把Key經過一個固定的算法函數既所謂的哈希函數轉換成一個整型數字,而後就將該數字對數組長度進行取餘,取餘結果就看成數組的下標,將value存儲在以該數字爲下標的數組空間裏。(或者:把任意長度的輸入(又叫作預映射,pre-image),經過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,而不可能從散列值來惟一的肯定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。)
      而當使用哈希表進行查詢的時候,就是再次使用哈希函數將key轉換爲對應的數組下標,並定位到該空間獲取value,如此一來,就能夠充分利用到數組的定位性能進行數據定位。
    • 數組的特色是:尋址容易,插入和刪除困難;數組

    • 而鏈表的特色是:尋址困難,插入和刪除容易。數據結構

    • 那麼咱們能不能綜合二者的特性,作出一種尋址容易,插入刪除也容易的數據結構?答案是確定的,這就是咱們要提起的哈希表,哈希表有多種不一樣的實現方法,我接下來解釋的是最經常使用的一種方法——拉鍊法,咱們能夠理解爲「鏈表的數組」,如圖:
      函數

      左邊很明顯是個數組,數組的每一個成員包括一個指針,指向一個鏈表的頭,固然這個鏈表可能爲空,也可能元素不少。咱們根據元素的一些特徵把元素分配到不一樣的鏈表中去,也是根據這些特徵,找到正確的鏈表,再從鏈表中找出這個元素。
    • Hash Table的查詢速度很是的快,幾乎是O(1)的時間複雜度。
    • hash就是找到一種數據內容和數據存放地址之間的映射關係
    • 散列法:元素特徵轉變爲數組下標的方法。
    • 散列表的查找步驟
      當存儲記錄時,經過散列函數計算出記錄的散列地址
      當查找記錄時,咱們經過一樣的是散列函數計算記錄的散列地址,並按此散列地址訪問該記錄性能

    • 散列衝突:不一樣的關鍵字通過散列函數的計算獲得了相同的散列地址。
      好的散列函數=計算簡單+分佈均勻(計算獲得的散列地址分佈均勻)
      哈希表是種數據結構,它能夠提供快速的插入操做和查找操做。
    • 優缺點
      優勢:不論哈希表中有多少數據,查找、插入、刪除(有時包括刪除)只須要接近常量的時間即0(1)的時間級。實際上,這隻須要幾條機器指令。
      哈希表運算得很是快,在計算機程序中,若是須要在一秒種內查找上千條記錄一般使用哈希表(例如拼寫檢查器)哈希表的速度明顯比樹快,樹的操做一般須要O(N)的時間級。哈希表不只速度快編程實現也相對容易
      若是不須要有序遍歷數據,而且能夠提早預測數據量的大小。那麼哈希表在速度和易用性方面是無與倫比的。
      缺點:它是基於數組的,數組建立後難於擴展,某些哈希表被基本填滿時,性能降低得很是嚴重,因此程序員必需要清楚表中將要存儲多少數據(或者準備好按期地把數據轉移到更大的哈希表中,這是個費時的過程)。學習

  • 問題2:軟件工程和程序設計關係?
  • 問題解決:軟件工程包含程序設計,已經不僅僅是侷限於編寫代碼,而是應該考慮程序的簡潔性,實用性。簡單來講,軟件工程考慮的要更加全面具體。測試

  • 問題3:漸進複雜度與時間複雜度異同?
  • 問題解決:一個是時間複雜度,一個是漸近時間複雜度。前者是某個算法的時間耗費,它是該算法所求解問題規模n的函數,然後者是指當問題規模趨向無窮大時,該算法時間複雜度的數量級。
    當咱們評價一個算法的時間性能時,主要標準就是算法的漸近時間複雜度,所以,在算法分析時,每每對二者不予區分,常常是將漸近時間複雜度T(n)=O(f(n))簡稱爲時間複雜度
    其中的f(n)通常是算法中頻度最大的語句頻度。語句頻度是一個算法中的語句執行次數。
    沒有循環的一段程序的複雜度是常數,一層循環的複雜度是O(n),兩層循環的複雜度是O(n^2)優化

  • 問題4:問題3中的語句頻度是什麼?
  • 問題解決:
    語句頻度和數據結構中時間複雜度的區別。
    1)時間頻度一個算法執行所耗費的時間,從理論上是不能算出來的,必須上機運行測試才能知道。但咱們不可能也沒有必要對每一個算法都上機測試,只需知道哪一個算法花費的時間多,哪一個算法花費的時間少就能夠了。而且一個算法花費的時間與算法中語句的執行次數成正比例,哪一個算法中語句執行次數多,它花費時間就多。一個算法中的語句執行次數稱爲語句頻度或時間頻度。記爲T(n)。
    (2)時間複雜度在剛纔提到的時間頻度中,n稱爲問題的規模,當n不斷變化時,時間頻度T(n)也會不斷變化。但有時咱們想知道它變化時呈現什麼規律。爲此,咱們引入時間複雜度概念。通常狀況下,算法中基本操做重複執行的次數是問題規模n的某個函數,用T(n)表示,如有某個輔助函數f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值爲不等於零的常數,則稱f(n)是T(n)的同數量級函數。記做T(n)=O(f(n)),稱O(f(n)) 爲算法的漸進時間複雜度,簡稱時間複雜度。在各類不一樣算法中,若算法中語句執行次數爲一個常數,則時間複雜度爲O(1),另外,在時間頻度不相同時,時間複雜度有可能相同,如T(n)=n^2+3n+4與T(n)=4n^2+2n-1它們的頻度不一樣,但時間複雜度相同,都爲O(n2)。
    按數量級遞增排列,常見的時間複雜度有:常數階O(1),對數階O(log2n),線性階O(n),線性對數階O(nlog2n),平方階O(n2),立方階O(n3),...,k次方階O(nk),指數階O(2n)。隨着問題規模n的不斷增大,上述時間複雜度不斷增大,算法的執行效率越低。
    複雜度關係
    c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n!

  • 問題5:在一個長度爲n的順序表的表尾插入一個新元素的漸進時間複雜度爲?
  • 問題解決:答案是0(1),
    由於是在表尾插入的,順序表讀取表尾元素是個常量級操做,插入操做無需移動所以也是個常量級操做。

結對互評

  • 20172304
  • 博客積極性很高,對於問題也有一些思考和認識,但願新學期能夠更好地提高本身。
  • 20172328
  • 博客內容詳細,對於一些知識點有本身的理解和簡單分析。不過在複雜度方面博客附圖中已經顯示了,我認爲2的n次方比n的3次方要大。但願能夠探討一下。

    課後習題

  • EX2.1 下列增加函數的階次是多少?
    a.10n^2+100n+1000
    n^2
    b.10n^3-7
    n^3
    c.2^n+100n^3
    2^n
    d.n^2 ·log(n)
    n^2 ·log(n)
  • EX2.4 請肯定下面代碼段的增加函數和階次
for(int count = 0 ; count < n ; count++)  
    for(int count2 = 0 ; count2 < n ; count2 = count2 + 2)
        {
            System.out.println(count,count2);
        }
}

由題,內層循環是n/2,外層循環是n,因此增加函數f(n) = n^2 /2,因此階次是O(n^2)。

  • EX 2.5 請肯定下面代碼段的增加函數和階次
for(int count = 0 ; count < n ; count++)
    for(int count2 = 0 ; count2 < n ; count2 = count2 * 2)
        {
            System.out.println(count,count2);
        }
}

由題,內層循環是log2n,外層循環是n,因此增加函數是nlog2n,因此階次是O(nlog2n)。

參考資料

相關文章
相關標籤/搜索