對於資料結構與演算法,我們首先給出乙個寬泛的定義:
從廣義上來說,資料結構是一組資料的儲存結構,演算法是運算元據的一組方法。從狹義上來說,資料結構與演算法是那些為人所知的解決方案,比如佇列,堆,棧,二分查詢,動態規劃等。那麼資料結構與演算法之間又是怎樣的藕斷絲連呢?
一言以蔽之,資料結構是為演算法服務的,演算法要作用在特定的資料結構之上,也就是它們之間是相互依存的,不能孤立演算法去談資料結構。
資料結構和演算法本身解決的是快和省的問題,也就是說時間和空間上的執行效率是衡量演算法的指標,為了更直觀的評估這項指標,就需要量化其複雜度的表示,即引入大o複雜度表示法
我們不再推導理論,而是直接給出乙個非常重要的規律,即:
**的執行時間t(n)與每條**的執行次數n成正比,這裡的先決條件是假定每行**執行的時間相同(即取指,解碼,執行的過程)再將這個規律總結成公式,就可以得到:
t (n
)=o(
f(n)
)t(n) = o(f(n))
t(n)=o
(f(n
))這裡的n表示的是資料的規模,t(n)是**的執行時間,f(n)是每行**執行的次數總和,大o表示的是一種函式關係,即t(n)與f(n)成正比,
既然時間複雜度僅表徵一種變化趨勢,那在時間複雜度評估時,就可以忽略一些對於變化趨勢沒有影響的因素,比如低階,常量,係數,我們只關注迴圈執行次數最多的**就行了。
常見的複雜度並不多,從低階到高階包括:o(1),o(logn),o(n),o(nlogn),o(n2)——
對應於快和省的需求,複雜度分析有兩個維度,時間複雜度和空間複雜度,先來看時間複雜度——
將時間複雜度細分,可以分為四類:最好情況時間複雜度,最壞時間複雜度,平均時間複雜度,均攤時間複雜度。我們逐一來看——
最好時間複雜度
:即在最理想的情況下,執行這段**的時間複雜度。
最壞時間複雜度
:即在最糟糕的情況下,執行這段**的時間複雜度。
平均時間複雜度
:即將每種可能情況下的執行次數加和再除以可能發生的情況總數,可以理解為概率論中的期望時間複雜度,即加權平均值
均攤時間複雜度
:即是有規律的加權平均值,是平均時間複雜度分析的特例,當遇到具體案例時,我們再介紹。
空間複雜度(space complexity)是對乙個演算法在執行過程中臨時占用儲存空間大小的量度,記做s(n)=o. (f(n))。這裡需要注意的是,往往我們會將一段**中為儲存元素時所申請的記憶體空間認為是空間複雜度,這是一種錯誤的認知,這段記憶體是固有的,而我們需要評估的是執行過程中占有空間隨著執行總行數的變化趨勢,它體現的是乙個動態的值。我們來判斷下面這段**的最好時間複雜度,最壞時間複雜度,均攤時間複雜度:
// 全域性變數,大小為10的陣列array,長度len,下標i。
int array=
newint[10
];int len =10;
int i =0;
// 往陣列中新增乙個元素
void
add(
int element)
// new_array複製給array,array現在大小就是2倍len了
array = new_array;
len =
2* len;
}// 將element放到下標為i的位置,下標i加一
array[i]
= element;
++i;
}
顯然,最快時間複雜度的情況是陣列空間足夠,直接將其儲存在下標為i的記憶體空間中,複雜度為o(1),最壞的情況即是陣列已滿,需要擴容長度為len*2的空間,複雜度為o(n)。我們可以認為需要擴容的概率為1/n+1.而不需要擴容的概率是n/n+1,需要擴容的複雜度n均攤到不需要擴容的n種情況,即可得到均攤時間複雜度為o(1).
日拱一卒,功不唐捐。
演算法複雜度分析
分析非遞迴演算法效率的通用方案 1.決定用哪個 哪些 引數作為輸入規模的度量 2.找出演算法的基本操作 作為一規律,它總是位於演算法的最內層迴圈中 3.檢查基本操作的執行次數是否只依賴輸入規模。如果它還依賴一些其他的特性,則最差效率 平均效率以及最優效率 如果必要 需要分別研究。4.建立乙個演算法基...
演算法複雜度分析
演算法分析的四個漸進表示法 一般,o裡的,取最小的 一般,裡的,取最大的 一般分析時間複雜度,且常考慮最壞複雜度,常用o分析 三法則 法則一 如果t1 n o f n t2 n0 o g n t1 n t2 n max o f n o g n t1 n t2 n o f n o g n 法則二 如果...
演算法複雜度分析
類別name 名字交換類排序 quicksort 快速排序 交換類排序 bubble sort 氣泡排序 選擇類排序 selection sort 選擇排序 選擇類排序 heapsort 堆排序插入類排序 insertion sort 插入排序 插入類排序 shell sort 希爾排序 bucke...