資料結構是資料儲存的方式,演算法則是處理資料的方法,通常我們通過分析演算法的時間複雜度和空間複雜度來判斷它的好壞。通常我們學資料結構的同時也會學習演算法,資料結構的不同就會導致演算法的不同,資料結構的選擇對演算法效率會產生重大的影響,所以資料結構與演算法緊密聯絡。乙個問題可能會有多種演算法,我們當然會採用最好的那個演算法,但是怎麼判斷乙個問題的好壞與否呢?我們一般會通過分析它們的時間複雜度和空間複雜度來進行比較。
一般情況下,演算法的基本操作重複執行的次數是模組n的某乙個函式f(n),因此,演算法的時間複雜度記做:t(n)=o(f(n))。在計算時間複雜度的時候,先找出演算法的基本操作,然後根據相應的各語句確定它的執行次數,再找出 t(n) 的同數量級(它的同數量級有以下:1,log(2)n,n,n log(2)n ,n的平方,n的三次方,2的n次方,n!),找出後,f(n) = 該數量級,若 t(n)/f(n) 求極限可得到一常數c,則時間複雜度t(n) = o(f(n))。
那麼什麼是空間複雜度呢?乙個程式的空間複雜度是指執行完乙個程式所需記憶體的大小。利用程式的空間複雜度,可以對程式的執行所需要的記憶體多少有個預先估計。乙個程式執行時除了需要儲存空間儲存本身所使用的指令、常數、變數和輸入資料外,還需要一些對資料進行操作的工作單元和儲存一些為現實計算所需資訊的輔助空間。乙個演算法的空間複雜度(space complexity)
s(n)定義為該演算法所耗費的儲存空間,它也是問題規模n的函式。漸近空間複雜度也常常簡稱為空間複雜度。空間複雜度(space complexity)是對乙個演算法在執行過程中臨時占用儲存空間大小的量度。乙個演算法在計算機儲存器上所占用的儲存空間,包括儲存演算法本身所占用的儲存空間,演算法的輸入輸出資料所占用的儲存空間和演算法在執行過程中臨時占用的儲存空間這三個方面。儲存演算法本身所占用的儲存空間與演算法書寫的長短成正比,要壓縮這方面的儲存空間,就必須編寫出較短的演算法。演算法在執行過程中臨時占用的儲存空間隨演算法的不同而異,有的演算法只需要占用少量的臨時工作單元,而且不隨問題規模的大小而改變,我們稱這種演算法是「就地"進行的,是節省儲存的演算法。演算法的輸入輸出資料所占用的儲存空間是由要解決的問題決定的,是通過參數列由呼叫函式傳遞而來的,它不隨本演算法的不同而改變。有的演算法需要占用的臨時工作單元數與解決問題的規模n有關,它隨著n的增大而增大,當n較大時,將占用較多的儲存單元,例如將快速排序和歸併排序演算法就屬於這種情況。
一般情況下,乙個程式在機器上執行時,除了需要儲存程式本身的指令、常數、變數和輸入資料外,還需要儲存對資料操作的儲存單元。若輸入資料所佔空間只取決於問題本身,和演算法無關,這樣只需要分析該演算法在實現時所需的輔助單元即可。若演算法執行時所需的輔助空間相對於輸入資料量而言是個常數,則稱此演算法為原地工作,空間複雜度為o(1)。關於o(1)的問題, o(1)是說資料規模和臨時變數數目無關,並不是說僅僅定義乙個臨時變數。舉例:無論資料規模多大,我都定義100個變數,這就叫做資料規模和臨時變數數目無關。就是說空間複雜度是o(1)。關於o(1)的問題, o(1)是說資料規模和臨時變數數目無關,並不是說僅僅定義乙個臨時變數。舉例:無論資料規模多大,我都定義100個變數,這就叫做資料規模和臨時變數數目無關,就是說空間複雜度是o(1)。當乙個演算法的空間複雜度為乙個常量,即不隨被處理資料量n的大小而改變時,可表示為o(1);當乙個演算法的空間複雜度與以2為底的n的對數成正比時,可表示為0(10g2n);當乙個演算法的空i司複雜度與n成線性比例關係時,可表示為0(n).若形參為陣列,則只需要為它分配乙個儲存由實參傳送來的乙個位址指標的空間,即乙個機器字長空間;若形參為引用方式,則也只需要為其分配儲存乙個位址的空間,用它來儲存對應實參變數的位址,以便由系統自動引用實參變數。
程式執行時所需儲存空間包括以下兩部分:
(1)固定部分。這部分空間的大小與輸入/輸出的資料的個數多少、數值無關。主要包括指令空間(即**空間)、資料空間(常 量、簡單變數)等所佔的空間。這部分屬於靜態空間(全域性變數、靜態變數等)。
(2)可變空間。這部分空間的主要包括動態分配的空間(即區域性變數),以及遞迴棧所需的空間等。這部分空間大小與演算法有關, 乙個演算法所需的儲存空間用f(n)表示。 s(n)=o(f(n)) 其中n為問題的規模,s(n)表示空間複雜度。
對於乙個演算法,其時間複雜度和空間複雜度往往是相互影響的。當追求乙個較好的時間複雜度時,可能會使空間複雜度的效能變差,即可能導致占用較多的儲存空間;反之,求乙個較好的空間複雜度時,可能會使時間複雜度的效能變差,即可能導致占用較長的執行時間。另外,演算法的所有效能之間都存在著或多或少的相互影響。因此,當設計乙個演算法(特別是大型演算法)時,要綜合考慮演算法的各項效能,演算法的使用頻率,演算法處理的資料量的大小,演算法描述語言的特性,演算法執行的機器系統環境等各方面因素,才能夠設計出比較好的演算法。
演算法是解決特定問題求解步驟的描述,在計算機中表現為指令的有限序列,並且每條指令表示乙個或多個操作。
演算法是電腦科學領域最重要的基石之一,但卻受到了國內一些程式設計師的冷落。許多學生看到一些公司在招聘時要求的程式語言五花八門就產生了一種誤解,認為學計算機就是學各種程式語言,或者認為,學習最新的語言、技術、標準就是最好的鋪路方法。其實大家都被這些公司誤導了。程式語言雖然該學,但是學習計算機演算法和理論更重要,因為計算機演算法和理論更重要,因為計算機語言和開發平台日新月異,但萬變不離其宗的是那些演算法和理論,例如資料結構、演算法、編譯原理、計算機體系結構、關係型資料庫原理等等。計算機基礎課程好比為「內功」,新的語言、技術、標準好比「外功」。整天趕時髦的人最後只懂得招式,沒有功力,是不可能成為高手的。
資料結構與演算法(四)
結構體 1 為什麼出現結構體 為了表達一些複雜的資料,而普通的基本資料型別變數無法表示 2 什麼是結構體 結構體是使用者根據自己的需求定義的一種新的資料型別 3 如何使用結構體 兩種方式 struct student int main void printf d s d n st.number,st...
資料結構與演算法《四》
一切推理都必須從觀察與實驗得來。伽利略 伽利雷 編寫乙個高效的演算法來搜尋 m x n 矩陣 matrix 中的乙個目標值 target。該矩陣具有以下特性 示例 現有矩陣 matrix 如下 1,4,7,11,15 2,5,8,12,19 3,6,9,16,22 10,13,14,17,24 18...
資料結構與演算法 基礎(四)
1.二分查詢 1.前提 該陣列是乙個有序陣列 2.思路 要考慮陣列中存在多個相同值的情況,以公升序陣列為例 向右收集相同值 temp mid 1 while temp right findval arr temp return list 2.插值查詢 1.前提 陣列是有序陣列 2.思路 同樣要考慮陣...