《編程珠璣》讀書筆記(三)

《編程珠璣》的第二部分講的是性能,第三部分講的是應用,所以我暫時跳過第二部分,直接看應用。

第十一章 排序

排序問題一直是面試的熱點!本章首先介紹了插入排序,然後介紹了快速排序,並提出了快速排序的幾種改進方法,例如雙向劃分、隨機數劃分、以及小範圍結合插入排序,三種的性能遞增。

排序免不了交換,書中特別指出將swap()函數寫入循環中會加速。

插入排序: 穩定,時間複雜度O(n^2),主要代碼如下
               
for ( i = 1 ; i < n ; i ++ )
{
    t = x[i];
    for( j = i ; j > 0 && x[j-1]>t;j--)
           x[j] = x[j-1];
    x[j] = t;
}

快速排序: 不穩定;時間複雜度O(nlogn)。

當出現n個相同元素組成的數組時,插入排序性能非常好,總運行時間爲O(n),但qsort性能非常糟糕,因此提出改進。

改進二:採用雙向劃分的方法,代入如下:
void qsort3( l , u )
  if l>=u
    return
  t = x[l];  i = l;  j = u + l;
  loop
      do  i++  while  i<=u && x[i]<t    //從左往右找到第一個大於等於t的數
      do  j--  while  x[j]>t           //從右往左找到第一風格小於等於t的數
      if  i > j
          break;
      swap( i , j )
  swap( l , j)
  qsort3( l , j-1 )
  qsort3( j+1 , u )

改進三:隨機元素劃分

改進四:快排+插入排序

第十二章 取樣問題

本章主要介紹了生成0~n-1區間內m個隨機數的三種方法,假設bigrand()函數返回一個隨機大整數,例如C庫函數rand()返回15位整數。
方法一:bigrand()%remaining<select,時間複雜度O(n)

方法二:C++zhongSTL的set集合,隨機生成一個數,插入set中,最後有序輸出。用空間換取時間,O(mlogn)

方法三:隨機打亂一個數組,輸出前m個即可,O(n+mlogn)

第十三章 搜索

本章介紹了5中表示隨機整數集合的數據結構:有序數組、有序鏈表、二叉樹、箱、位向量。各自性能如下:
集合表示 初始化操作 insert操作 輸出操作 總時間 空 間
有序數組 1 m m O(m^2) m
有序鏈表 1 m m
O(m^2)
2m
二叉樹 1 logm m
O(mlogm)
3m
m 1 m
O(m)
3m
位向量 n 1 n
O(n)
n/b

有序數組 IntSetArr類 實現於 P129;
有序鏈表 IntSetList類 實現於 P130;
二叉樹    IntSetBST類 實現於 P132;
位向量   IntSetBitVec類 實現於 P134;
箱         IntSetBins類   實現於  P135;
詳細代碼見《附錄E》

本章的邊欄介紹了“拼寫檢查器”的實現。

第十四章 堆

本章首先介紹了堆的性質:一是有序,二是形狀,以及用數組來表示堆。

堆的兩個關鍵函數是:siftup()自底向上,siftdown()自頂向下,代碼分別實現於P144、P145。

優先級隊列(插入和刪除操作很頻繁)是一種常見的數據結構,主要有三種實現方法:有序序列、無序序列、堆(介於前兩者之間的折中方法),三者性能比較如下:
數據結構 一次insert時間 一次extract時間 兩種操作各n次時間
有序序列 O(n) O(1) O(n^2)
O(logn) O(logn) O(nlogn)
無序序列 O(1) O(n) O(n^2)

用堆實現優先級隊列的代碼在P147,建議動手實踐!

最後介紹了堆排序算法,分兩步進行:建堆+排序,O(nlogn),習題2,3對堆排序進行了改進,暫未明白。
堆排序代碼:
for i = [2 , n)
  siftup(i)
for( i = n ; i >= 2 ; i-- )
  swap( l , i )
  siftdown(i-1);
//x[l]是前i個元素中最大的,將它和x[i]交換使得有序序列多一個元素,因此下移保持堆平衡


第十五章 字符串

本章主要介紹了三種字符串的應用:

1、生成詞典,統計單詞的個數,分別用C++和C實現。
     C++實現使用了STL的set和map,其實本質是平衡搜索樹。
     C實現使用的是散列表,比C++速度更快。

2、最長重複字串,用後綴數組實現,O(nlogn),需要額外的n個指針空間。

3、生成隨機文本,主要了解k階文本-->k接馬爾科夫鏈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章