演算法簡介:
一、資料結構與演算法的關係
雖然本門課程叫「資料結構」,但經常會講到演算法,以及它們之間的關係。在市面上也經常有諸如「資料結構與演算法分析」這樣名字的書。
實際上,資料結構與演算法是依存關係。只談資料結構而拋棄演算法,則資料是「死」的,沒有活力的;只談演算法而拋棄資料結構,則演算法無法有所依賴的操作物件,只是空談。對於程式來說,資料結構賦予其血肉骨骼,演算法賦予其靈魂思想,二者合一才是完整的程式,二者缺一不可。因此,我們在學習資料結構的時候,經常要學習演算法的相關知識。
二、演算法定義
定義:演算法(algorithm):演算法是解決特定問題求解步驟的描述,在計算機中表現為指令的有限序列,並且每條指令表示乙個或多個動作。
對於給定的問題,是可以有多種演算法來解決的。
現實世界中問題千奇百怪,演算法當然也就千變萬化,沒有通用的演算法可以解決所有的問題。甚至對於一些問題,優秀的演算法卻不見得適合它。(例如,對於資料量較少(萬以下)的資料排序,快速排序演算法的執行效率並沒有比氣泡排序快上很多。)
演算法示例:輾轉相除法求兩個正整數的最大公約數
輾轉相除法,又名歐幾里得演算法(euclidean algorithm),大約2023年前由歐幾里得在其著作《幾何原本》中提出,是世界上已知最古老的演算法。
演算法描述:設兩數為a、b(a>b),求最大公約數的步驟如下:
⒈用a除以b,得到其商q和餘數r
⒉若r=0,則最大公約數就是b,演算法結束
⒊若r!=0,則令a=b,b=r
⒋迴圈執行,回到步驟1
**描述:
/************
*函式euclidean_algorithm()
*入參:兩個整數int m,int n
*返回值:兩數的最大公約數
*功能:計算兩個數的最大公約數
**************/
int euclidean_algorithm(int m,int n)
while(r!=0);
return m;
}構造乙個演算法的常見方法有:遞推法、遞迴法、窮舉法、貪心法、分治法、動態規劃法、迭代法、分支界限法、回溯法等。
一些大名鼎鼎的演算法:
⒈輾轉相除法:已知世界上最古老的演算法
⒉割圓術:劉徽首創,祖沖之改進,計算圓周率
⒊秦九韶演算法:大大簡化多項式的計算
⒋快速排序演算法:20世紀十大演算法之一
⒌赫夫曼編碼:資料壓縮的基本演算法
⒍rsa加密:現代計算機網路資料加密演算法的基礎
⒎蒙特卡洛搜尋樹演算法:人工智慧基礎演算法,讓計算機「可以像人類般思考」的演算法
三、演算法的特性
演算法具有5個基本特性:輸入、輸出、有窮性、確定性、可行性
1、輸入輸出:
演算法具有0個或多個輸入,至少有1個輸出。輸出的形式可以是列印字元,也可以是返回值等形式。
2、有窮性:
有窮性:指演算法在執行有限的步驟後,自動結束而不會出現無限迴圈,並且每個步驟在可接受的時間內完成。
3、確定性:
確定性:演算法的每一步驟都具有確定的含義而不會出現二義性。演算法在一定條件下,只有一條執行路徑,相同的輸入只能得到唯一的輸出結果。演算法的每個步驟被精確定義而無歧義。
4、可行性:
可行性:演算法的每一步必須是可行的,也就是說,每一步都可以通過執行有限次數完成。可行性意味著演算法可以轉換成上機程式並得到正確結果。
四、演算法設計要求
好的演算法,應該具有正確性、可讀性、健壯性、高效率和低儲存量的特徵。
1、正確性:
正確性:演算法的正確性是指演算法至少應該具有輸入、輸出和加工處理無歧義性、能正確反應問題的需求、能夠得到問題的正確答案。
演算法的正確性大體上分為4個層次:
⒈演算法程式沒有語法錯誤;
⒉演算法程式對於合法的輸入資料能夠產生滿足要求的輸出結果;
⒊演算法程式對於非法的輸入能夠得出滿足規格說明的資訊;
⒋演算法程式對於精心選擇的、甚至刁難的測試資料都有滿足要求的輸出結果。
證明乙個複雜演算法的正確性需要數學推導方法的證明,而若證明以上4個層次都正確的話代價非常昂貴,因此一般情況下,我們把層次3作為乙個演算法是否具有正確性的標準。
2、可讀性:
可讀性高有助於人們理解演算法,晦澀難懂的演算法往往會隱含錯誤,不易被發現,並且難於實現、除錯和修改。
有時,我們可能為了追求極致(例如致力於用最少的**來描述演算法)而書寫出一些難以理解的演算法,這樣的**真的不好理解,也許除了計算機自己,沒幾個人能讀懂這樣的**。可讀性是演算法(也包括實現該演算法的**)好壞的很重要的指標。
3、健壯性:
乙個好的演算法還應能對輸入資料不合法的情況做出合適的處理,例如若輸入的不能為負數(例如時間、年齡、工號、距離等)的資料為負數時演算法要能夠報錯。
4、時間效率高和儲存量低:
最後,好的演算法還應具備時間效率高和儲存量低的特點。
五、演算法效率的度量方法
1、事後統計方法
事後統計方法:這種方法主要是通過設計好的測試程式和資料,利用計算機計時器對不同演算法編制的電腦程式的執行時間進行比較,從而確定演算法執行效率的高低。
2、事前分析估算方法
事前分析估算方法:在電腦程式編寫前,根據統計方法對演算法進行估算。
乙個用高階語言編寫的程式在計算機上執行時間取決於以下因素:
⒈演算法採用的策略、方法
⒉編譯產生的**質量
⒊問題的輸入規模
⒋機器執行指令的速度
其中第1條是演算法好壞的根本,第2條取決於軟體,第4條取決於硬體效能。也就是說,乙個程式的執行時間,依賴於演算法的好壞和輸入的規模。
六、演算法的時間複雜度
1、演算法的時間複雜度與大o記法
定義:演算法的時間複雜度:在進行演算法分析時,語句總的執行次數t(n)是乙個關於問題規模n的函式,進而分析t(n)隨n的變化情況確定t(n)的數量級。演算法的時間複雜度記做:t(n)=o(f(n)),它表示隨著問題規模n的增大,演算法執行時間的增長率和函式f(n)的增長率相同,稱作演算法的漸進時間複雜度,簡稱為時間複雜度。其中f(n)是問題規模n的某個函式。
這樣用o()來體現演算法時間複雜度的記法,我們稱之為大o記法。
大o記法表示演算法時間複雜度增長率的上限,即隨著資料規模n的增大,所耗時的可能最大增長率。
2、推導大o階的方法
已知語句執行次數t(n),推導乙個演算法時間複雜度大o階的方法如下:
⒈用常數1取代t(n)中的所有加法常數
⒉在修改後的執行次數函式中,只保留最高端項
⒊如果最高端項存在且不是1,則去除與這個項相乘的常數
示例:分析以下演算法的時間複雜度
void matrixm(int n)}}
}第一步:計算語句執行次數t(n)
對於演算法來說,我們要求得語句執行次數,需要先分析每一條語句的語句頻度。對於以上**來說,其每一條語句的語句頻度為:
void matrixm(int n)
該語句的語句頻度}}
}將以上每個語句頻度相加,得到
t(n)=2*n^3+3*n^2+2*n+1
第二步:保留最高次項
t(n)----->o(2*n^3)
第三步:去除最高次項係數
t(n)----->o(n^3)
即t(n)=o(n^3)
3、常見時間複雜度
從計算時間上可以把演算法分成兩類:可以用多項式來對其計算時間限界的演算法,稱為多項式時間演算法(polynomial time algorithm);而計算時間用指數函式限界的演算法稱為指數時間演算法(exponential time algorithm)。
常見的多項式時間演算法有o(1)、o(logn)、o(n)、o(nlogn)、o(n2)、o(n3)。
常見的指數時間演算法有o(2^n)、o(n!)、o(n^n)。
以下是常見的一些t(n)的時間複雜度o(n)
//見附圖1
常用演算法的時間複雜度所耗費的時間從小到大依次是:
o(1) < o(logn) < o(n) < o(nlogn) < o(n^2) < o(n^3) < o(2^n) < o(n!) < o(n^n)
對於o(n^3)以及以後的時間複雜度,過大的n都會使得演算法耗時大大增加,因此過於大的時間複雜度一般不予討論。
4、最壞情況與平均情況
針對不同的資料n,同樣的演算法所執行的時間也不完全相同。例如在n個資料中查詢乙個資料,最好情況是第乙個資料就是,那麼這時的時間複雜度就是o(1),而最壞的情況就是資料在最後,那麼這時的時間複雜度就是o(n)。最壞情況執行時間是一種保證,即執行時間不會更壞。通常情況下,若無特殊指定,演算法的時間複雜度都指最壞情況下的時間複雜度。
而平均情況的時間複雜度是從概率角度來看,這個資料在每乙個位置是完全隨機的。平均執行時間是所有情況中最有意義的,因為它是期望的執行時間。可在現實中,平均執行時間很難通過事前分析得到,需要執行一定量的實驗資料後估算出來。
七、演算法空間複雜度
演算法的空間複雜度通過計算演算法所需的儲存空間實現,演算法的空間複雜度記做s(n)=o(f(n)),其中n為問題的規模,f(n)為語句關於n所佔儲存空間的函式。
一般情況下,乙個程式執行時,除了儲存本身指令、常數、變數和輸入量之外,還需要儲存對資料操作的儲存單元,即演算法在執行中的輔助單元。若演算法執行時所需輔助空間相對於資料輸入量而言是個常數,則此演算法為原地工作,空間複雜度為o(1)。
《資料結構與演算法》之資料結構簡介
資料結構 資料 結構,資料結構是計算機儲存 組織資料的方式。資料結構是指相互之間存在一種或多種特定關係的資料元素的集合。通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率。資料結構往往同高效的檢索演算法和索引技術有關。一 資料的邏輯結構 指反映資料元素之間的邏輯關係的資料結構,其中的邏輯關...
(一)資料結構與演算法簡介
目標 掌握資料結構與演算法的理論知識 補齊演算法短板 梳理前端與演算法結合點,不再紙上談兵,將演算法用於實戰 三部曲 刷題 前端與資料結構 演算法的結合點 在工作中與資料結構 演算法大交道 資料結構與演算法是什麼 資料結構 計算機儲存 組織資料的方式,就像鍋碗瓢盆 演算法 一系列解決問題的清晰指令,...
資料結構與演算法筆記(一)簡介
資料結構與演算法至關重要。計算機是乙個記憶體有限,計算能力有限的機器,如果每段時間處理的資料增加量大於每段時間能處理的資料量,時間越長,電腦執行會越來越慢直至宕機。複雜度是衡量程式執行的效率的量度因素。執行 消耗計算時間和計算空間,衡量的是時間複雜度和空間複雜度。複雜度是乙個關於輸入量n的函式。假如...