js視角的數據結構和算法(一)

什麼是數據結構

在我們的認知中,整潔一定是比混亂更讓人有舒適感。髒亂差的房間和乾淨整潔的房間,基本上都偏向後者。生活如此,編程如此。繁雜而又零散的數據訪問和修改起來是災難性的,效率極低。所謂的數據結構,就是數據的組織,管理和存儲格式。讓無組織的散兵遊勇成爲紀律嚴明的軍隊,高效精準的訪問和修改數據。針對的場景不同,衍生的類別也就不同(數組,鏈表,樹,圖…),但統稱數據結構。

什麼是算法

所謂算法,就是一系列用於解決特定邏輯或某個問題的程序與指令的集合。程序=數據結構+算法。單純的談論數據結構和單純討論算法都太片面,二者結合纔是王道。一道數學題的解決過程是算法(如1加到100),一個特定邏輯的實現是算法(如數組去重),它看起來無形,但用起來應該有意。

數據結構和算法有什麼用

如果你只想停留在基礎水準,複製粘貼能跑就行,就等於一輩子柴米油鹽,那修煉絕世武功確實沒用。數據結構和算法和SEO(搜索引擎優化),設計模式這些東西都是一樣的,是可以提高生活質量的錦上添花系列功能。不至於是生與死的區別,但確實是活着和活得好的區別,下面簡單羅列幾個學好數據結構和算法看得見的好處。

開闊視野,豐富解決問題的思路
性能優化,更快更省
面試,提高核心競爭力

算法好壞的差異

在我們學習過程中,即便自己不夠優秀,也應該清楚優秀應該是什麼樣的,算法也是如此。即便我們暫時寫不出效率高佔用內存小的算法,也應該知道真正高效的算法應該是怎樣的。

  • 算法一,首屏渲染加載1個小時,耗費內存1個G
  • 算法二,首屏渲染1s,耗費內存1M
  • 同樣的網站,你更願意訪問基於哪個算法的呢?差異顯而易見。

算法好壞的衡量標準

不同機器配置不一樣,且即便是同一臺機器不同時刻內存佔用也不一定相同,出於諸多考慮,算法在運行時的比較效率,結果未必符合預期。所以,算法的比較都是預估,即在程序真正運行前就給出評估結果。評估依據有兩個,時間複雜度和空間複雜度。

  • 耗時最短,內存消耗最小的更快更省算法,被稱之爲理想算法。
  • 當然,實際問題上多是犧牲時間換空間或者犧牲空間換時間
  • 具體問題具體分析,最適合解決當前問題的算法纔是最好的。

時間複雜度

時間複雜度可看成是語句總執行次數隨問題規模變化而變化的一個數學函數,記作T(n)=O(f(n))。其中f(n)是關於問題規模n的某個函數。算法執行時間增長率和f(n)相同,稱作算法漸進時間複雜度。常說的時間複雜度,指的也是漸進時間複雜度。這種用大O()來體現時間算法複雜度的記法,稱爲大O記法。具體情況不同,運行時間也會有差異,比如最好情況,最壞情況,平均情況,而我們所說的時間複雜度,基本都是建立在最壞運行時間基礎上。

問題規模是什麼?

  • 可以簡單理解爲最大計算量,1加到100,問題規模就是100,1加到1000,問題規模就是1000

漸進時間複雜度存在意義何在?

  • 既生瑜何生亮?有時間複雜度了,漸進時間複雜度有啥用?
  • 存在即合理,假設有算法A,B.。算法A在問題規模小於100時效率高,算法B在問題規模大於100時效率高
  • 根本無法直接決定哪個算法好,需要結合具體場景,問題規模小於100,A優於B,大於100,B優於A。
  • 所以需要一個界定條件,或者說整體變化規律完成比較,這就是漸進時間複雜度存在的意義

時間複雜度的計算規則

  • 執行次數函數爲常數量級,視爲O(1)
    在這裏插入圖片描述

  • 執行次數函數多項式只保留最高項,次高項忽略
    在這裏插入圖片描述

  • 執行次數函數多項式最高項有常係數則忽略該係數
    在這裏插入圖片描述

常見時間複雜度排序

在這裏插入圖片描述

  • 大於等於立方階的要考慮是不是代碼寫錯了,或考慮換一種算法
  • 優化到常數當然最理想,實際到線性階和對數階的居多

空間複雜度

空間複雜度是對存儲空間的計算。也用大O記法,S(n)=O(f(n))

空間複雜度的計算

  • 存儲空間固定不變,爲O(1),如簡單定義一個變量
let num=1
  • 輸入數據和數組或集合大小成線性,空間複雜度爲O(n)
  • 數組定義但未在循環中開闢新空間,空間複雜度也爲O(n)
let arr =Array(n); //空間複雜度爲O(n)


//空間複雜度爲O(n)
function print(n){
    const arr=[1,2,3,4,5]
    for (let j = 0; j < n; j++) {
       console.log(arr[j])
    }
}



  • 嵌套循環且在循環中開闢新空間,空間複雜度爲平方階
function computed(n){
let arr=[]
for (let i = 0; i < n; i++) {
    arr[i]=i //每次數組賦值都會申請一個空間存儲變量 n 
    for (let j = 0; j < n; j++) {
        arr[i][j]=j//每次數組賦值都會申請一個空間存儲變量 n
    }
}
}
  • 常見的空間複雜度只有 O(1)、O(n)、O(n2)。其他的話很少會用到,若碰到,有可能代碼寫錯了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章