《漫畫演算法》筆記 上篇

2022-06-10 10:42:06 字數 3630 閱讀 9332

漫畫演算法-小灰的演算法之旅

魏夢舒(@程式設計師小灰)著

小灰用漫畫(可愛的手繪小倉鼠)的形式,給演算法這顆「炮彈」包上了「糖衣」,讓演算法的為力潛藏於內,外表不再嚇人,變得萌萌噠,q彈可愛。

本書通過主人公小灰,用漫畫的形式講述了演算法與資料結構的基礎知識、複雜多變的演算法面試及演算法的實際應用。

「學習演算法,我們不需要死記硬背那些冗長複雜的背景知識、底層原理、指令語法......需要做的是領悟演算法思想、理解演算法對記憶體空間和效能的影響,以及開動腦筋去尋求解決問題的最佳方案。相比程式設計領域的其他技術,演算法更純粹,更接近數學,也更具有趣味性。」 -- 作者說

演算法

algorithm。始於計算出1+2+3+4...+10000的結果。首先把從1到10000這10000個數字兩兩分組相加,如下:

1 + 10000 = 10001

2 + 9999 = 10001

3 + 9998 = 10001

......

一共有多少組這樣結果相同的和呢?有10000/2即5000組,即結果:(1 + 10000) * 10000 / 2 = 50005000

在數學上稱這種等差數列求和的方法為:高斯演算法

在數學領域:演算法是用於解決一類問題的公式和思想。

在計算機領域:演算法本質是一串行程式指令,用於解決特定的運算和邏輯問題。衡量演算法好壞的重要標準有兩個:

應用:運算、查詢、排序、尋找最優路線、面試等。

資料結構

資料結構是演算法的基石。如果把演算法比喻成美麗靈動的舞者,那麼資料結構就是舞者腳下廣闊而堅實的舞台。

data structure,是資料的組織、管理和儲存格式,其使用的目的是為了高效地訪問和修改資料。

資料結構組成方式:

時間複雜度

是對乙個演算法執行時間長短的量度,用大o表示,記作t(n) = o(f(n))

直白地講,時間複雜度就是把程式的相對執行時間函式t(n)簡化為乙個數量級,這個數量級可以是n、n²、n³等。

推導出時間複雜度,有如下幾個原則:

比如:執行次數是t(n) = 3n,最高端項為3n,省去係數3,轉化的時間複雜度為t(n) = o(n)

執行次數是t(n) = 5logn,最高端項為5logn,省去係數5,轉化的時間複雜度為t(n) = o(logn)。5logn,數學中的對數。

執行次數是t(n) = 2,只有常數量級,轉化的時間複雜度為t(n)=o(1)

執行次數是t(n) = 0.5n² + 0.5n,最高端項為0.5n²,省去係數0.5,轉化的時間複雜度為t(n) = o(n²)

誰更節省時間呢?結論如下:

o(1) < o(logn) < o(n) < o(n²)

空間複雜度

space complexity。是對乙個演算法在執行過程中臨時占用儲存空間大小的度量,用大o表示,記作s(n) = o(f(n))

陣列

有限個,在記憶體中順序儲存。

記憶體是由乙個個連續的記憶體單元組成的,每乙個記憶體單元都有自己的位址。

陣列中的每乙個元素,都儲存在小小的記憶體單元中,並且元素直接緊密排列,既不能打亂元素的儲存順序,也不能跳過某個儲存單元進行儲存。

操作:插入、刪除的時間複雜度都是o(n)

優勢:非常高效的訪問能力,只要給出下標,就能找到對應元素。

劣勢:插入、刪除效率低下。陣列元素連續緊密地儲存在記憶體中,插入、刪除元素都會導致大量元素被迫移動,影響效率。

陣列適合讀操作多、寫操作少的場景。鍊錶和陣列正好相反。

鍊錶

一種在物理上非連續、非順序的資料結構,由若干節點(node)所組成。

單向鍊錶的每乙個節點包含兩部分,存放資料的變數data,指向下乙個節點的指標next。

鍊錶的第乙個節點被稱為頭結點,最後乙個節點被稱為尾節點。尾結點的下乙個節點指向空。

雙向鍊錶,每乙個節點除了擁有 data 和 next,還擁有指向前置節點的 prev 指標。

陣列在記憶體中的儲存方式是順序儲存,鍊錶 在記憶體中的儲存順序是隨機儲存。

陣列在記憶體中占用了連續完整的儲存空間,而鍊錶採用了見縫插針的方式,鍊錶的沒乙個節點分布在記憶體的不同位置,依靠next指標關聯起來。這樣可以靈活有效地利用零散的碎片空間。

鍊錶操作:

;鍊錶的插入和刪除的時間複雜度:如果不考慮插入、刪除操作之前查詢元素的過程,只考慮純粹的插入、刪除操作,時間複雜度為o(1)

陣列 vs 鍊錶:陣列能夠利用下標快速定位元素,對於讀操作多、寫操作少的場景非常使用。而鍊錶的有事在於能靈活的進行插入和刪除操作,適用於讀操作少、寫操作多的場景。

棧和佇列

資料儲存的物理結構和邏輯結構:

邏輯結構:精神層面,抽象的概念,依賴於物理結構而存在。

棧:stack。一種線性資料結構,棧中的元素只能先進後出(filo,first in last out)。最早進入的元素存放的位置叫作棧底,最後進入的元素存放的位置叫作棧頂。用陣列、鍊錶均可以實現。

棧的基本操作:

入棧、出棧的時間複雜度:o(1),因為只會影響到最後乙個元素。

佇列:queue。一種線性資料結構,佇列中的元素只能先進先出(fifo,first in first out)。佇列的出口端叫作隊頭(front),佇列的入口端叫作隊尾(rear)。用陣列、鍊錶均可以實現。

佇列的基本操作:

額外:迴圈佇列、雙端佇列、優先佇列。

雜湊表

雜湊表:也稱雜湊表,hash table。是儲存 key-value 對映的集合,時間複雜度接近於o(1)。本質上也是乙個陣列。

雜湊函式:通過某種方式,把 key 和陣列下標進行轉換的函式。

雜湊表的讀寫操作:

讀操作(get):通過給定的key,在雜湊表中查詢對應的value。

tree,是n個節點的有限集。有如下特點:

樹的最大層級樹,被稱為樹的高度或深度。

相關節點

二叉樹

樹的一種特殊形式。樹的每個節點最多有2個孩子節點。

二叉樹的兩個孩子節點,乙個被稱為左孩子,乙個被稱為右節點。

二叉樹有兩種特殊形式:滿二叉樹、完全二叉樹。

滿二叉樹:乙個二叉樹的所有非葉子節點都存在左右孩子,並且所有葉子節點都在同一層接上。簡言之,滿二叉樹的每乙個分支都是滿的。

完全二叉樹:對乙個有n個節點的二叉樹,按層級順序編號,則所有節點的編號為從1到n。如果這個樹所有節點和同樣深度的滿二叉樹的編號為從1到n的節點位置相同,則這個二叉樹為滿二叉樹。

一棵樹,若為滿二叉樹,那麼一定是完全二叉樹。反之,不一定。

在記憶體中儲存:

二叉樹的應用:查詢操作、維持相對順序。

二叉樹的遍歷:

從節點之間位置關係的角度:

從更巨集觀的角度:

二叉堆:本質上是一種完全二叉樹。

二叉堆的根節點,叫作堆頂。最大堆的堆頂是整個堆中最大元素,最小堆的堆頂是整個堆中最小元素。

優先佇列:基於二叉堆實現:

觀後感:回想起了很多大學學習時的場景與概念(專業:軟體工程)

JDBC學習筆記 上篇

二 獲取連線connection 三 得到執行sql語句的物件statement 四 執行sql語句,並返回結果 五 處理結果集 查詢得到的resultset 總結記錄一下jdbc的學習筆記,mysql版本5.7,驅動版本5.1.47 1.註冊驅動的方式如下 drivermanager.regist...

Vue的學習筆記(上篇)

vue 是一套用於構建使用者介面的漸進式框架。與其它大型框架不同的是,vue 被設計為可以自底向上逐層應用。vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合。另一方面,當與現代化的工具鏈以及各種支援類庫結合使用時,vue 也完全能夠為複雜的單頁應用提供驅動。v model指...

《C 沉思錄》學習筆記 上篇

1.2 說了 hello world 後再做什麼 32 2.技術 27 30 2.2 在簇中分配物件 28 2.3 應用器 操縱器和函式物件 29 2.4 將應用程式從輸入輸出中分離出來 30 3.庫 23 26 3.3 庫設計就是語言設計 3.4 語言的設計就是庫的設計 4.碎碎念 因為肺炎的事情...