1. 程式人生 > >【極客時間】資料結構與演算法總結

【極客時間】資料結構與演算法總結

【極客時間】資料結構與演算法總結:

02|

資料結構是為演算法服務的,演算法要作用在特定的資料結構之上。

20個最常用的最基礎的資料結構與演算法:

10個數據結構:陣列、連結串列、棧、佇列、散列表、二叉樹、堆、跳錶、圖、Trie樹

10個演算法:遞迴、排序、二分查詢、搜尋、雜湊演算法、貪心演算法、分治演算法、回溯演算法、動態規劃、字串匹配演算法

03|

大O時間複雜度表示法,表示程式碼執行時間隨資料規模增長的變化趨勢,也叫做漸進時間複雜度。

時間複雜度分析:

1.只關注迴圈執行次數最多的一段程式碼,我們通常忽略掉公式中的常量、低階、係數。只需要記錄一個最大階的量級。

2.加法法則:總複雜度等於量級最大的那段程式碼的複雜度。

T1(n)=O(f(n)),T2(n)=O(g(n))

T(n)=T1(n)+T2(n)=max(O(f(n)),O(g(n)))=O(max(f(n),g(n)))

3.乘法法則:巢狀程式碼的複雜度等於巢狀內外程式碼複雜度的乘積。

T1(n)=O(f(n)),T2(n)=O(g(n))

T(n)=T1(n)*T2(n)=max(O(f(n))*O(g(n)))=O(max(f(n)*g(n)))

幾種常見的時間複雜度:

多項式量級:

常量階 O(1)

只要演算法中不存在迴圈語句、遞迴語句

對數階 O(logn)

線性階 O(n)

線性對數階 O(nlogn)

歸併排序、快速排序的時間複雜度

平方階 O(n 2 ^2 ),立方階以及k次方階

非多項式量級(擁有這個時間複雜度的演算法問題是NP問題):

指數階O(2

n ^n )

階乘階 O(n!)

空間複雜度分析:

表示演算法的儲存空間與資料規模之間的增長關係。

越高階複雜度的演算法,執行效率越低,從低階到高階可以是:

在這裡插入圖片描述

(圖來自於極客時間。)

04|

複雜度分析:

最好情況時間複雜度

最壞情況時間複雜度

平均情況時間複雜度

均攤時間複雜度:在程式碼執行的所有複雜度情況中絕大部分是低級別的複雜度。個別情況是高級別複雜度且發生具有時序關係時,可以將個別高級別複雜度均攤到低級別複雜度上,基本上均攤結果就等於低級別複雜度。

對一個數據結構進行一組連續操作中,大部分情況下時間複雜度都很低,只有個別情況下時間複雜度比較高,而且這些操作之間存在前後連貫的時序關係,這個時候,我們就可以將這一組操作放在一塊分析,看能否將較高時間複雜度那次操作的耗時,平攤到其他那些時間複雜度比較低的操作上。

在能夠運用均攤時間複雜度分析的場合,一般均攤時間複雜度就等於最好情況時間複雜度

加權平均時間複雜度/期望時間複雜度:把每種情況發生的概率也考慮進去

05|

陣列(Array)是一種線性表資料結構。它用一組連續的記憶體空間,來儲存一組具有相同型別的資料。

線性表:陣列、連結串列、佇列、棧等

非線性表(資料之間並不是簡單的前後關係):二叉樹、堆、圖

連續的記憶體空間和相同型別的資料:

因為這個,才有了陣列的特性“隨機訪問”

定址公式:

一維陣列:

a[i]_address=base_address+i*data_type_size

二維陣列:

對於m*n的陣列,

a[i][j]_address=base_address+(i*n+j)*data_type_size

陣列和連結串列的區別:

陣列支援隨機訪問,根據下標隨機訪問的時間複雜度O(1)

在某些特殊場景下,並不一定非要追求陣列中資料的連續性,所以可以將多次刪除操作集中在一起執行,可以提高刪除效率。

可以先記錄下已經刪除的資料。每次的刪除操作並不是真正地搬移資料,只是記錄資料已經被刪除。當陣列沒有更多空間儲存資料時,再觸發一次真正地刪除操作,這樣做可以大大減少刪除操作導致地資料搬移。

應用:JVM標記清除垃圾回收演算法的核心思想。

JVM標記清除演算法:

大多數主流虛擬機器採用可達性分析演算法來判斷物件是否存活,在標記階段,會遍歷所有GC ROOTS,將所有GC ROOTS可達的物件標記為存活。只有當標記工作完成後,清理工作才會開始。

不足:1.效率問題。標記和清理效率都不高,但是當知道只有少量垃圾產生時會很高效。

2.空間問題。會產生不連續的記憶體空間碎片。

容器與陣列的選擇:

ArrayList:可以將很多陣列操作的細節封裝起來,並且支援動態擴容(每次儲存空間不夠的時候,它都會將空間自動擴容1.5倍大小)

擴容操作涉及記憶體申請和資料搬移,是比較耗時,所以最好在建立ArrayList的時候事先指定資料大小。

Java ArrayList無法儲存基本型別,比如int,long,需要封裝為Integer、Long類。關注效能則可以使用陣列。

業務開發直接使用容器。