資料結構與演算法 - 時間複雜度
目錄
一、資料結構概要
二、演算法概要
三、時間複雜度簡介
四、求解時間複雜度
一、資料結構
資料結構是相互之間存在一種或多種特定關係的資料元素的集合。在各類實際應用問題中,資料元素之間總是存在著各種關係,描述資料元素之間關係的方法稱為結構。通常,可根據資料元素之間所存在的關係的不同特徵,用4類基本結構予以描述:
(1)集合:指結構中的資料元素之間只存在“同屬一個集合”的關係。
間
(2)線性結構:指結構中的資料元素之間存在“一個對一個”的關係。
數
(3)樹形結構:指結構中的資料元素之間存在“一個對多個”的關係。
(4)圖形結構:指結構中的資料兀素之間存在“多個對多個”的關係。

基本結構
二、演算法
2.1、演算法定義:
通常,演算法( Algorithm)是指解決問題的一種方法或一個過程。如果把問題看作函式,則演算法就能把輸入轉化成輸出。
在資料結構中,演算法是對特定問題求解步驟的一種描述,是指令的有限序列。
同一問題可以有多種不同的求解演算法,一個給定的演算法可以用來描述解決特定問題的一個具體的求解方案。瞭解對於同一問題的多種求解法有助於對演算法的執行效率進行分析和比較,加深對演算法的理解。
2.2、演算法設計:
演算法設計技術是用演算法解題的一般性方法,用於解決不同計算領域的多種問題。
常用的演算法設計技術主要有蠻力法、分治法、減治法、變治法、時空權衡、動態規劃、貪婪技術等。
1、蠻力法
蠻力法是一種簡單直接地解決問題的方法,常常直接基於問題的描述和所涉及的概念定義。可以應用蠻力法解決廣闊領域的各種問題,它是唯一一種幾乎什麼問題都能解決的一般性方法。
2、分治法
分治法將問題的例項劃分為若干個較小的例項,對這些較小例項遞迴求解,然後合併這些解,以得到原始問題的解。
3、減治法
減治法通過建立一個問題給定例項的解和同樣問題較小例項解的關係,採用自頂向下(遞迴)或自底向上(非遞迴)的策略進行求解。
減治法有三個主要的變種:減一技術(每次迭代減去一個常量,通常為1)、減半技術(每次選代減去一個常量因子,通常為2)、減可變規模技術(每次選代規模減小的模式不同)。
4、變治法
變治法基於變換的思想,將問題變換成更容易求解的形式。
變治法有三個策略:例項化簡(把問題的例項變換為相同問題的另一個例項,使問題的求解更加容易)、改變表現(將一個問題例項的表現改變為同樣例項的另一種表現)、問
題化簡(把一個給定的問題變換成另一個可以用已知演算法求解的問題)
5、時空權衡
時空權衡主要有空間換時間和時間換空間兩種技術。在早期的計算機應用中,硬體資源限制嚴重,許多問題包含的大量資料無法整體裝入計算機中一次處理,需要通過時間換空間技術才能解決;但在硬體資源十分豐富的現在,演算法設計通常採用空間換時間技術
空間換時間技術有兩類,輸入增強技術,通過對問題輸入的部分或全部做預處理,以
來提高演算法的時間效率。
加速問題的求解;預構造技術,通過使用額外的空間來實現更快或更方便的資料存取。
6、動態規劃
動態規劃是一種對具有交疊子問題的問題進行求解的技術。一般來說,這樣的子問題出現在求解給定問題的遞推關係中,而該遞推關係包含了相同型別更小問題的解。它通過對每個較小的子問題求解一次並記錄在表中,從而避免對交疊子問題的重複求解,從表中得出原始問題的解。
7、貪婪技術
貪婪技術通過一系列步驟來構造問題的解,每一步對目前構造的部分解做一個擴充套件,直到獲得問題的完整解為止。貪婪技術核心是,所做的每一步選擇都必須滿足可行、區域性
最優和不可取消原則。
2.3、演算法分析
估量一個演算法或計算機程式效率的方法,稱為演算法分析。所謂演算法分析,就是對一個演算法所消耗的資源的估算。演算法分析的目的主要是考察演算法的時間效率和空間需求,分別從演算法的時間複雜度和空間複雜度兩個方面進行分析,如果存在多個可行的演算法,則根據時間複雜度或空間複雜度這兩個指標選取效率最高最優的演算法。
進行演算法分析需要了解的基本概念:
(1)問題規模:一般是指輸入量的數目。
(2)基本操作:通常是指具有完成該操作所需的時間與運算元的取值無關的性質的
操作。
(3)代價:即實現一個演算法所需的資源需求。
(4)增長率:是指當問題規模增大時,演算法代價增長的速率
(5)最佳、最差和平均代價:分別是指演算法實現對資源需求的最小、最大和平均情況。
三、時間複雜度
演算法的時間複雜度是指演算法對時間的需求。一個演算法的執行時間通常與所解決問題的規模大小有關。
例如,在排序問題中,排序的元素個數n就是問題規模,排序演算法中基本操作語句的重複執行次數隨著問題規模n的增大而增加。
一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式f(n)。因此,演算法的時間效率可記為: T(n)= O(f(n))
表示隨問題規模n的增大,演算法的執行時間的增長率和f(n)的增長率相同,稱作演算法的漸近時間複雜度,簡稱時間複雜度。表示式中O的含義是指T(n)的數量級。一般情況下,當Tn)為多項式時,可只取最高次冪項,且係數也可省略。例如:T(n)=3n²+n-9 則T(n)=O(n²)。
一般地,演算法所消耗的時間是每條語句的執行時間之和。每條語句的執行時間是其執行次數(頻度)與該語句執行一次所需時間的乘積。在計算機中,程式語句的執行時間與計算機的效能有關,因此在分析演算法的執行效率時,假設語句執行時間與機器無關,只考慮所有語句的執行次數。
演算法中的基本操作可以理解為演算法程式中最深層迴圈內的語句中的基本操作,它的執行次數(頻度)與包含它的語句的執行次數相同。
通常情況下,時間複雜度的表示以O(f(n))形式體現,如O(1)、O(n)、O(n²)、O(logn)、O(2^n )等。根據f(n)的具體形式,常稱某個演算法的時間複雜度是常量階O(1)線性階O(n)、平方階O(n²)、對數O(logn)、指數階O(2^n)等。常數階表示演算法的時間複雜度與問題規模n無關。當一個演算法的時間複雜度體現為指數階時,通常將認為不是一個有效的演算法。
空間複雜度是指演算法執行過程對計算機儲存空間的要求,稱為演算法的空間複雜度。類似於時間複雜度,記為 S(n)= O(f(n)) 其中n是問題的規模
通常,執行一個演算法程式除了需要儲存空間存放本身所用的指令、常數、變數和輸出資料外,還需要一些輔助空間用於對資料進行處理及儲存處理過程中的中間資訊。若輸入資料所佔的空間只取決於問題本身而與演算法無關,則只需要分析除了輸入和程式之外的輔助空間需求。演算法的空間複雜度通常就是指這種輔助空間需求的大小。
四、求解時間複雜度
最後通過例項來加深對時間複雜度的理解:
- 【例1】以下演算法實現奇偶性判斷,試分析時間複雜度。
int isOdd (int n) { if(n % 2 == 0) {//(1) return 1://(2) }else { return 0;//(3) } } 分析:語句(1)執行1次,根據表示式n%2==0結果,可能執行語句(2)或語句(3)1次。 語句總執行次數為T(n)=1+1=2 因此,演算法的時間複雜度為常數階O(1)。演算法的執行時間與問題規模n無關。
- 【例2】遞迴演算法實現求n!,試分析時間複雜度。
int fact(int n) { if(n <= 1) { return 1;//(1) }else { return(n * fact(n-1));//(2) } } 分析:語句(1)的時間複雜度為O(1),遞迴呼叫fact(n-1)的時間是T(n-1),因此可得 當n≤1時,T(n) = O(1), 當n>1時:T(n) = T(n-1) + O(1),T(n-1)=0(1)+T(n-2),T(n-2)=O(1)+T(n-3)........ 由此可推出 T(n)=(n-1)0(1)+T(1)=O(n) 因此遞迴求n!演算法的時間複雜度為O(n)。