第8章 高效演算法設計讀書筆記

2021-07-02 05:51:41 字數 3249 閱讀 5853

演算法分析初步

8.1.1 漸進時間複雜度 ——最大連續和,給出乙個序列,找到i,j使連續和盡量大

使用列舉思想:列舉每乙個可能的序列首和序列尾

for( i = 1; i <= n; i++)

if( sum > best) best = sum;

}}

8.1.2 上界分析 ——三重迴圈,最壞情況下內層迴圈需要n次,故t(n) = o(n的3次方)(上界)

對這個程式進行簡化:連續子串行之和等於兩個字首和之差

for( i = 1; i <= n; i++)

}

8.1.3 分治法 ——分治法一般分為3個步驟

1、劃分問題:劃分成子問題 ;     把序列分成個數相等的兩半

2、遞迴問題:遞迴解決子問題;  分別求出完全位於左半或者右半的最佳序列

3、合併問題:合併子問題的解      求出起點位於左半終點位於右半的序列,並和子問題最優解比較

遞迴方程 t(n) = 2t(n/2) + o(n); t(1) = 1;  的解是t(n) = o(n log n)

再談排序和搜尋

8.2.1 歸併排序 ——也可以用分治法分成三個步驟

1、劃分問題:劃分成子問題 ;     把序列分成個數相等的兩半

2、遞迴問題:遞迴解決子問題;  兩半分別排序

3、合併問題:合併子問題的解      把兩個有序表合併成乙個

#includevoid sort( int* a, int x, int y, int* t);

int a = ;

int t[100];

int main(void)

void sort( int* a, int x, int y, int* t)

else

} for( i = x; i < y; i++)

} }

逆序對數(尚沒有仔細看懂)

8.2.2 快速排序 ——暫時略

8.2.3 二分查詢 ——折半查詢的思想,不過只針對有序序列

#includevoid sort( int* a, int x, int y, int* t);                              // 利用之前的分治方法進行排序

int main();

int t[100];

int x, y, m, v, i, num;

scanf("%d", &m);

sort( a, 0, 9, t);

for( i = 0; i < 9; i++) printf("%d ", a[i]);

printf("\n");

x = 0; y = 8;

num = 0;

while( x < y)

else if( a[v] <= m) x = v;

else y = v;

} return 0;

}void sort( int* a, int x, int y, int* t)

for( i = x; i < y; i++) a[i] = t[i];

}}

如果序列中有重複,且重複的為所求數字,那麼用原來的二分法就只能求得最中間的位置,需要進行一些小的修改

while( x < y)		

else y = v; // 若求下界則是當相等時改變y

}

範圍統計:給出乙個序列,以及m個詢問,對於每個詢問(a, b),求閉區間 [a,b] 內個數

即求 a 所在的下界 l 和 b 所在的上界 r ,而後求區間 [ l, r]長度

遞迴與分治 ——【tbc】

貪心法 ——排序、取當前最優解

8.4.1 最優裝載問題 ——裝輕的比裝重的划算,故將所有物體按重量從小到大排列

8.4.2 部分揹包問題 ——部分選取,一定能讓總重量恰好為c。

8.4.3 乘船問題 ——兩個下表

i,j來表示當前最重和最輕的人

if(最輕的人

+最重的人 

標準重)  //

浪費最少

else  //此時最重的只能自己乘一條船,往下尋找能和最輕的人同乘的 最重的人

8.4.4 選擇不相交區間 —— 有

n個區間

(ai, bi)

。如果區間

a能夠完全覆蓋

b則選取

a就是 不划算的,依據

bi將所有區間排序,那麼第乙個元素一定是在最優解中

排序後b1 < b2

①a1 >= a2

時,區間

1被區間

2完全包含,所以選取區間

2是不划算的

②a1 < a2

時,區間

1中位於

a2左邊的部分對結果並沒有影響,真正有影響 的是區間1 中

a2到b1部分,這一部分被區間

2完全包含,所以選取區間

2是不划算的

所以應該選取第乙個區間,然後需尋找此後與此區間不相交的第乙個區間

8.4.5 區間選點問題 ——小區間被滿足時大區間也會被滿足,所以在區間包含的情況下大區 間不用考慮。依據

bi將所有區間排序,然後取最後乙個點

[s,t]

外的部分都切掉,因為存在 無意義。依據

ai將所有區間排序,如果第乙個區間起點不是

s,則無解。否則選取最長區間,隨後設定此區間尾

bi為新的起點。

8.4.7 huffman編碼 ——證明用

huffman

樹可以得出最優解需要以下兩個結論:

①如果編碼a

是編碼b

的字首,那麼

a對應的結點一定為

b所對應結點的祖先。 而兩個葉結點不存在祖先後代的關係

②最有字首碼一定可以寫成二叉樹

構造一顆最優編碼樹(huffman演算法)

:每棵子樹權值等於相應字元的頻率,每次 選擇權值最小的樹組成一顆權值為兩樹之和的新樹,放回集合中。滿足以下兩個性質

①設x,y

是使用頻率最小的兩個字元,存在字首碼使二者具有相同碼長,僅有 最後一位不同

(保留了最優解)

②設z為

x,y的父結點,把

z看成頻率具有

x,y頻率之和的字元,那麼此樹是 包含z而無

x,y字元的集合的最優解

(最優子結構性質

)

第8周讀書筆記

構建之法 讀書筆記 part1 開學了這麼久還沒有自覺的看過課本,讀課本都是在老師布置任務的時候有需要再看的。這週就自己主動的看了一點這本書。翻開這本書就帶來了不小的視覺衝擊。軟體 程式 演算法的概念深入我心,但是書上把 演算法 改成了 軟體工程 開發乙個軟體的過程是多方面的,源程式 資料 軟體架構...

第1 2 16章讀書筆記

第一章 概論 原文 乙個好的軟體,即使功能和同類軟體區別不大,但卻會讓人感覺到非常好用。這就是軟體的使用者體驗。使用者體驗和資料結構,演算法沒有直接的關係,但是很多非常成功的軟體就贏在這個方面。軟體還要處理 不同語言,不同地區的使用者對介面和功能的不同需求,這個叫做軟體的國際化和本地化。1.使用者體...

《HeadFirst設計模式》讀書筆記 第7章

定義 外觀模式 facade pattern 提供了乙個統一的介面,用來訪問子系統中的一群介面。外觀定義了乙個高層介面,讓子系統更加容易使用。從上面的圖可以看出,facade類對子系統進行了一下封裝,客戶只需要和facade類打交道,不需要接觸子系統中的各個類,也不需要了解子系統中各個類間的關係。從...