《我的第一本算法书》 - 学习记录
目錄
- 0. 算法基礎知識
- 0-1. 什么是算法
- 0.1.1 算法和程序的區別
- 0.1.2 排列整數的算法:排序
- 0.1.3 如何選擇算法
- 0-2. 運行時間的計算方法
- 0.2.1 輸入數據的量和運行時間之間的關系
- 0.2.2 求運行時間
- 0.2.3 運行時間的表示
- 一. 數據結構
- 1-1. 什么是數據結構
- 1-2 鏈表
- 1-3 數組
- 1-4 棧
- 1-5 隊列
- 1-6 哈希表
- 1-7 堆
- 未完待續~
0. 算法基礎知識
0-1. 什么是算法
算法就是計算或者解決問題的步驟。
0.1.1 算法和程序的區別
????????算法和程序有些相似,區別在于程序是以計算機能夠理解的編程語言編寫而成的,可以在計算機上運行,而算法是以人類能夠理解的方式描述的,用于編寫程序之前。不過,在這個過程中到哪里為止是算法、從哪里開始是程序,并沒有明確的界限。
????????就算使用同一個算法,編程語言不同,寫出來的程序也不同;即便使用相同的編程語言,寫程序的人不同,那么寫出來的程序也是不同的。
0.1.2 排列整數的算法:排序
- 查找最小的數字并交換:選擇排序;
- 用計算機能理解的方式構思解法:算法的設計。
0.1.3 如何選擇算法
???????在算法的評判上,考量的標準各有不同。
???????如,簡單的算法對人來說易于理解,也容易被寫成程序,而在運行過程中不需要耗費太多空間資源的算法適用于內存小的計算機。
???????不過,一般都是注重算法的運行時間,即從輸入數據到輸出結果這個過程所花費的時間。
0-2. 運行時間的計算方法
0.2.1 輸入數據的量和運行時間之間的關系
???????對 10 個數字排序和對 1 000 000 個數字排序,我們很容易想到后者的運行時間更長。那么,實際上運行時間會長多少呢?后者是前者的100 倍,還是1 000 000 倍?
????????就像這樣,不光要理解不同算法在運行時間上的區別,還要了解根據輸入數據量的大小,算法的運行時間具體會產生多大的變化。
0.2.2 求運行時間
???????最為現實的方法就是在計算機上運行一下程序,測試其實際花費的時間。但是,由于計算機的不同會產生偏差。
所以通常用 “步數” 來描述運行時間?!? 步”就是計算的基本單位。
0.2.3 運行時間的表示
???????如,理論上選擇排序的運行時間,計算并簡化后如下:
???????從上式可知,排序算法的運行時間與輸入數據量 n 的平方成正比。假設某個算法的運行時間如下:
???????那么,這個結果就可以用O(n^3) 來表示。如果運行時間為:
???????這個結果就可以用O(nlogn) 來表示。
???????通過這種表示方法,我們可以直觀地了解算法的 時間復雜度(常用大O 符號來表述)。
O 這個符號的意思是“忽略重要項以外的內容”,讀音同Order。O(n^2) 的含義就是“算法的運行時間最長也就是n平方 的常數倍”,準確的定義請參考相關專業書籍。
一. 數據結構
1-1. 什么是數據結構
???????數據存儲于 內存 時,決定了 數據順序* 和 位置關系 的便是 “數據結構”。
???????通常,數據在內存中是呈線性排列的,但是也可使用指針構造出類似 “樹形” 的復雜結構。
1-2 鏈表
鏈表 是數據結構之一,數據呈線性排列:
-
單向鏈表:每個數據都有1 個 “指針”,它指向下一個數據的內存地址;
鏈表中,數據一般都是分散存儲于內存中的,無需存儲在連續空間內。
???????因為數據都是分散存儲的,所以如果想要訪問數據,只能從第1 個數據開始,順著指針的指向 順序訪問。比如,想要找到Red 這一數據,就得從Blue 開始訪問。
-
循環鏈表:在鏈表 尾部使用指針,并且讓它指向鏈表頭部的數據;
-
雙向鏈表:為數據設定 兩個指針,并且讓它們分別 指向前、后數據。
雙向鏈表存在的缺點:
1-3 數組
???????數組: 數據呈線性排列。與前面的鏈表不同,在數組中,訪問數據十分簡單,而添加和刪除數據比較耗工夫。
???????數據 按順序存儲 在內存的 連續空間內。
???????由于數據是存儲在連續空間,所以每個數據的內存地址,都可以通過數組下標算出,并借此直接訪問目標數據(即隨機訪問)。
【數組內存操作】
???????如果要向數組中添加新數據,必須把目標位置后面的數據一個個移開。所以,如果在數組頭部添加數據,就需要 O(n) 的時間,刪除操作同理。
補充說明:
???????在鏈表和數組中,數據都是線性地排成一列。在鏈表中訪問數據較為復雜,添加和刪除數據較為簡單;
???????而在數組中訪問數據比較簡單,添加和刪除數據卻比較復雜。我們可以根據哪種操作較為頻繁來決定使用哪種數據結構。
| 鏈表 | 慢 | 快 | 快 |
| 數組 | 快 | 慢 | 慢 |
1-4 棧
棧:數據呈線性排列,是一種最后添加的數據最先被取出(即“后進先出”)的結構,我們稱為Last In First Out,簡稱LIFO。
應用: 深度優先搜索算法
想要訪問中間的數據時,就必須通過出棧操作將目標數據移到棧頂才行。
在只需要訪問最新數據時,使用它就比較方便了
1-5 隊列
也呈線性排列,與 棧 有些相似。“先進先出”的結構,稱為First In First Out,簡稱FIFO。
應用: 廣度優先搜索算法
區別: 隊列中 添加 和 刪除 數據的操作分別是 在兩端進行 的。
往隊列中添加數據時,數據被加在最后面。
從隊列中取出(刪除)數據時,是從最前面,也就是最早入隊的數據開始的。不能直接訪問位于中間的數據。
1-6 哈希表
在哈希表這種數據結構中,使用“哈希函數”,可以使數據的查詢效率得到顯著提升。
哈希表存儲的是由鍵(key)和值(value)組成的數據。
一般來說,可以把 鍵 當成數據的標識符,把 值 當成數據的內容。
總結:
???????在哈希表中,可以利用哈希函數快速訪問到數組中的目標數據。
???????如果發生哈希沖突,就使用鏈表進行存儲(這樣一來,不管數據量為多少,都能夠靈活應對)。
???????如果數組的空間太小,使用哈希表的時候容易發生沖突,線性查找的使用頻率也會更高;反過來,如果數組的空間太大,就會出現很多空箱子,造成內存的浪費(因此,給數組設定合適的空間非常重要)。
1-7 堆
堆 是一種圖的樹形結構,被用于實現“優先隊列”(priority queues)
???????優先隊列是一種數據結構,可以自由添加數據,但取出數據時要從最小值開始按順序取出。
???????在堆的樹形結構中,各個頂點被稱為“結點”(node),數據就存儲在這些結點中。
~~~
未完待續~
總結
以上是生活随笔為你收集整理的《我的第一本算法书》 - 学习记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java-数组的使用
- 下一篇: vue控制元素的隐藏和显示