前端要不要學習數據結構
作為一名IT技術人員,需要不斷的完善自己的知識體系來提升自己,類似數據結構、網絡等。在工作中大部分時間我們都是做應用層面的開發,有時候對數據結構、算法這些基本功要求不是很高,但是一些基本得知識點我們還是需要掌握。
到底什么是數據結構
是不是經常聽別人說數據結構、算法、程序 = 數據結構 + 算法等,那么到底什么是數據結構?
數據結構本身是一個抽象的概念,沒有具體的標准,比如我們用的電腦,我可以說電腦這種結構由cpu、主板、顯卡、內存、硬盤、電源、聲卡、網卡等組成。如 vue-cli 初始化的項目由 main.js、src等組成。所以不需要去糾結到底什么是數據結構,數據結構本身只是一層抽象的概念,從字眼上可以理解為數據與數據之間存在一種或多種關系的數據元素集合。
從不同的角度,數據結構可以理解為邏輯結構、物理結構。可以理解為邏輯結構是在計算機中的存儲形式,物理結構是計算機怎么存儲數據;
邏輯結構:數據元素之間的相互關系
- 集合結構 平等關系,在同一個集合中
- 線性結構 一對一關系
- 樹形結構 一對多關系
- 圖形結構 多對多關系
物理結構:數據的邏輯結構在計算機中的存儲形式
- 順序存儲 類似連續的一個列表
- 鏈式存儲 存在一個指針指向需要的元素
算法
解決問題的步驟我們叫方法,在計算機中稱算法,在計算機中表現為指令的有限序列;通常一個問題有很多種方法,有些方法很巧妙,有些看起來比較繞,這些方法是有差異的,我們通常在計算機中通過時間復雜度、空間復雜度來衡量一個算法的好壞。
時間復雜度
時間復雜度並不是說代碼執行的具體的時間,而是表示代碼執行時間隨問題規模或者數據規模增長的變化趨勢,也叫漸進時間復雜度,簡稱為時間復雜度。我們都知道一個算法花費的時間與算法中語句的執行次數肯定成正比例,哪一個算法中語句執行次數多,它花費時間就多。
1 function get (n) { 2 let i = 0; // 一次 3 let name = '' // 一次 4 } 5 // 總共就是2次
如上所示,總共執行了2次,但是通常我們處理的事情這個n 可能不是一個固定值,所以我們把一個算法中的語句執行次數記為函數T(n),n為問題規模,隨着問題規模n的變化,算法執行的時間也會變化,為了更好的分析這個時間的變化比,用O()來表示時間復雜度的記法,我們稱為大O記法。語句執行總的次數T(n)跟O() 有如下公式
T(n) = O(f(n)),它表示隨着問題規模n 的增大,算法執行時間的增長率和f(n)的增長率相同,其中f(n)是問題規模n的某個函數
大O推導方法
我們一般通過以下方法來分析一個算法的時間復雜度
- 用常數1代替運行中的所有的加法常數
- 在修改后的運行次數函數中,只保留最高階項
- 如果最高階項存在且不為1,則去除與這個項相乘的常數(除法也是變相的相乘)
常數階:O(1)
如果算法執行所需要的臨時空間不隨着某個變量n的大小而變化,即此算法空間復雜度為一個常量,可表示為O(1)
1 function run () { 2 let value = 100 3 value += 10 4 console.log(value) 5 // 共執行3次,根據大O 推導法,把常數換成1,則結果是O(1) 6 }
線性階:O(n)
1 function run (n) { 2 for(let i = 0; i < n; i++) { 3 console.log(i) 4 } 5 } 6 // 共執行n次,根據大O推導法,只取最高階,所以是 O(n)
平方階__O( n^2 )
function run (n) { for(let i = 0; i < n ; i++ ) { for(let j = 0; j < n ; j++ ) { console.log(j) } } } /* 外層i的循環執行一次,內層j的循環就要執行n次 因為外層執行n次,那么總的就需要執行n*n次, 也就是需要執行n^2次,根據大O推導法:O(n^2)
*/
常見的復雜度
執行次數 | 復雜度 | 非正式術語 |
12 | O(1) | 常數階 |
2n+3 | O(n) | 線性階 |
4n2+zn+2 | O(n2) | 平方階 |
4log2n+21 | O(logn) | 對數階 |
3n+2log3n+15 | O(nlogn) | nlogn階 |
4n3+3n2+22n+11 | O(n3) | 立方階 |
2n | O(2n) | 指數階 |
時間復雜度耗費時間從小到大依次排列
O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
練習
1 function run(n) { 2 for (let i = 0; i < n; i++) { 3 for (let j = i; j < n; j++) { 4 console.log(`${n},hello word`) 5 } 6 } 7 } 8 run(10)
當 i = 0 時,內循環執行 n 次運算,當 i = 1 時,內循環執行 n - 1 次運算……當 i = n - 1 時,內循環執行 1 次運算。
所以,執行次數 T(n) = n + (n - 1) + (n - 2)……+ 1 = n(n + 1) / 2 = n^2 / 2 + n / 2。
根據上文說的 大O推導法 可以知道,此時時間復雜度為 O(n^2)。
空間復雜度
算法的空間復雜度通過計算算法所需的存儲空間,公式記住 S(n) = O(f(n)),其中n 為問題規模,f(n)為關於n 所占存儲空間的函數。
數據結構與算法的關系
數據結構和算法是相輔相成的,雖然可以單獨分開為兩個東西,但是對於計算機來說把他們分開,那么他們將變得十分無聊。
數據結構研究的是組織數據的方式,比如數組,他就是一種組織數據的方式,就是一種數據結構。但是有了數據結構,不一定有算法。數據結構是算法的基礎,比如數據結構為數組,使用數組,可以寫出冒泡、快排等算法。
數據結構為算法服務,算法作用在特定的數據結構之上。