欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何用JavaScript學習算法復雜度

 更新時間:2021年04月30日 15:19:10   作者:淺笑·  
這篇文章主要介紹了如何用JavaScript學習算法復雜度,對算法感興趣的同學,一定要看一下

概述

在本文中,我們將探討 “二次方” 和 “n log(n)” 等術語在算法中的含義。

在后面的例子中,我將引用這兩個數(shù)組,一個包含 5 個元素,另一個包含 50 個元素。我還會用到JavaScript中方便的performance API來衡量執(zhí)行時間的差異。

const smArr = [5, 3, 2, 35, 2];

const bigArr = [5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2, 5, 3, 2, 35, 2];

什么是 Big O 符號?

Big O 表示法是用來表示隨著數(shù)據(jù)集的增加,計算任務難度總體增長的一種方式。盡管還有其他表示法,但通常 big O 表示法是最常用的,因為它著眼于最壞的情況,更容易量化和考慮。最壞的情況意味著完成任務需要最多的操作次數(shù);如果你在一秒鐘內就能恢復打亂魔方,那么你只擰了一圈的話,不能說自己是做得最好的。

當你進一步了解算法時,就會發(fā)現(xiàn)這非常有用,因為在理解這種關系的同時去編寫代碼,就能知道時間都花在了什么地方。

當你了解更多有關 Big O 表示法的信息時,可能會看到下圖中不同的變化。我們希望將復雜度保持在盡可能低的水平,最好避免超過 O(n)。

O(1)

這是理想的情況,無論有多少個項目,不管是一個還是一百萬個,完成的時間量都將保持不變。執(zhí)行單個操作的大多數(shù)操作都是 O(1)。把數(shù)據(jù)寫到數(shù)組、在特定索引處獲取項目、添加子元素等都將會花費相同的時間量,這與數(shù)組的長度無關。

const a1 = performance.now();
smArr.push(27);
const a2 = performance.now();
console.log(`Time: ${a2 - a1}`); // Less than 1 Millisecond


const b1 = performance.now();
bigArr.push(27);
const b2 = performance.now();
console.log(`Time: ${b2 - b1}`); // Less than 1 Millisecond

O(n)

在默認情況下,所有的循環(huán)都是線性增長的,因為數(shù)據(jù)的大小和完成的時間之間存在一對一的關系。所以如果你有 1,000 個數(shù)組項,將會花費的 1,000 倍時間。

const a1 = performance.now();
smArr.forEach(item => console.log(item));
const a2 = performance.now();
console.log(`Time: ${a2 - a1}`); // 3 Milliseconds

const b1 = performance.now();
bigArr.forEach(item => console.log(item));
const b2 = performance.now();
console.log(`Time: ${b2 - b1}`); // 13 Milliseconds

O(n^2)

指數(shù)增長是一個陷阱,我們都掉進去過。你是否需要為數(shù)組中的每個項目找到匹配對?將循環(huán)放入循環(huán)中是一種很好的方式,可以把 1000 個項目的數(shù)組變成一百萬個操作搜索,這將會使你的瀏覽器失去響應。與使用雙重嵌套循環(huán)進行一百萬次操作相比,最好在兩個單獨的循環(huán)中進行 2,000 次操作。

const a1 = performance.now();
smArr.forEach(() => {
    arr2.forEach(item => console.log(item));
});
const a2 = performance.now();
console.log(`Time: ${a2 - a1}`); // 8 Milliseconds


const b1 = performance.now();
bigArr.forEach(() => {
    arr2.forEach(item => console.log(item));
});
const b2 = performance.now();
console.log(`Time: ${b2 - b1}`); // 307 Milliseconds

O(log n)

我認為關于對數(shù)增長最好的比喻,是想象在字典中查找像 “notation” 之類的單詞。你不會在一個詞條一個詞條的去進行搜索,而是先找到 “N” 這一部分,然后是 “OPQ” 這一頁,然后按字母順序搜索列表直到找到匹配項。

通過這種“分而治之”的方法,找到某些內容的時間仍然會因字典的大小而改變,但遠不及 O(n) 。因為它會在不查看大部分數(shù)據(jù)的情況下逐步搜索更具體的部分,所以搜索一千個項目可能需要少于 10 個操作,而一百萬個項目可能需要少于 20 個操作,這使你的效率最大化。

在這個例子中,我們可以做一個簡單的快速排序。

const sort = arr => {
  if (arr.length < 2) return arr;

  let pivot = arr[0];
  let left = [];
  let right = [];

  for (let i = 1, total = arr.length; i < total; i++) {
    if (arr[i] < pivot) left.push(arr[i]);
    else right.push(arr[i]);
  };
  return [
    ...sort(left),
    pivot,
    ...sort(right)
  ];
};
sort(smArr); // 0 Milliseconds
sort(bigArr); // 1 Millisecond

O(n!)

最糟糕的一種可能性是析因增長。最經(jīng)典的例子就是旅行的推銷員問題。如果你要在很多距離不同的城市之間旅行,如何找到在所有城市之間返回起點的最短路線?暴力方法將是檢查每個城市之間所有可能的路線距離,這是一個階乘并且很快就會失控。

由于這個問題很快會變得非常復雜,因此我們將通過簡短的遞歸函數(shù)演示這種復雜性。這個函數(shù)會將一個數(shù)字去乘以函數(shù)自己,然后將數(shù)字減去1。階乘中的每個數(shù)字都會這樣計算,直到為 0,并且每個遞歸層都會把其乘積添加到原始數(shù)字中。

階乘只是從 1 開始直至該數(shù)字的乘積。那么6!是1x2x3x4x5x6 = 720。

const factorial = n => {
  let num = n;

  if (n === 0) return 1
  for (let i = 0; i < n; i++) {
    num = n * factorial(n - 1);
  };

  return num;
};
factorial(1); // 2 Milliseconds
factorial(5); // 3 Milliseconds
factorial(10); // 85 Milliseconds
factorial(12); //  11,942 Milliseconds

我原本打算顯示factorial(15),但是 12 以上的值都太多,并且使頁面崩潰了,這也證明了為什么需要避免這種情況。

結束語

我們需要編寫高性能的代碼似乎是一個不爭得事實,但是我敢肯定,幾乎每個開發(fā)人員都創(chuàng)建過至少兩重甚至三重嵌套循環(huán),因為“它確實有效”。Big O 表示法在表達和考慮復雜性方面是非常必要的,這是我們從未有過的方式。

以上就是如何用JavaScript學習算法復雜度的詳細內容,更多關于JS算法復雜度的資料請關注腳本之家其它相關文章!

相關文章

  • 微信小程序調用支付接口的完整流程記錄

    微信小程序調用支付接口的完整流程記錄

    我們在做小程序支付相關的開發(fā)時,總會遇到這些難題,下面這篇文章主要給大家介紹了關于微信小程序調用支付接口的完整流程,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-02-02
  • js購物車實現(xiàn)思路及代碼(個人感覺不錯)

    js購物車實現(xiàn)思路及代碼(個人感覺不錯)

    提起購物車想必只有在一些購物網(wǎng)站上才可以看得到,下面為大家介紹下使用js實現(xiàn)的購物車,感興趣的朋友可以參考下
    2013-12-12
  • Javascript獲取當前時間函數(shù)和時間操作小結

    Javascript獲取當前時間函數(shù)和時間操作小結

    這篇文章主要介紹了Javascript獲取當前時間函數(shù)和時間操作小結,本文根據(jù)項目實際需求總結而來,需要的朋友可以參考下
    2014-10-10
  • 基于JavaScript實現(xiàn)的折半查找算法示例

    基于JavaScript實現(xiàn)的折半查找算法示例

    這篇文章主要介紹了基于JavaScript實現(xiàn)的折半查找算法,結合實例形式分析了折半查找的原理、操作步驟及javascript實現(xiàn)折半查找的相關操作技巧與注意事項,需要的朋友可以參考下
    2017-04-04
  • JavaScript閉包實例講解

    JavaScript閉包實例講解

    眾所周知,JavaScript沒有塊級作用域,只有函數(shù)作用域。那就意味著定義在函數(shù)中的參數(shù)和變量在函數(shù)外部是不可見的,而在一個函數(shù)內部任何位置定義的變量,在該函數(shù)內部任何地方都可見
    2014-04-04
  • JS驗證逗號隔開可以是中文字母數(shù)字

    JS驗證逗號隔開可以是中文字母數(shù)字

    這篇文章主要介紹了JS驗證逗號隔開可以是中文字母數(shù)字 的相關資料,需要的朋友可以參考下
    2016-04-04
  • 深入理解JavaScript系列(4) 立即調用的函數(shù)表達式

    深入理解JavaScript系列(4) 立即調用的函數(shù)表達式

    大家學JavaScript的時候,經(jīng)常遇到自執(zhí)行匿名函數(shù)的代碼,今天我們主要就來想想說一下自執(zhí)行
    2012-01-01
  • JS正則表達式常見用法實例詳解

    JS正則表達式常見用法實例詳解

    這篇文章主要介紹了JS正則表達式常見用法,結合實例形式分析了javascript元字符、分組符、修飾符、量詞基本含義,并結合具體案例形式分析了javascript正則基本使用技巧,需要的朋友可以參考下
    2018-06-06
  • ES6 Promise.race的用法詳解

    ES6 Promise.race的用法詳解

    本文主要介紹了ES6 Promise.race的用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • 深入理解ES6學習筆記之塊級作用域綁定

    深入理解ES6學習筆記之塊級作用域綁定

    本篇文章主要介紹了深入理解ES6學習筆記之塊級作用域綁定,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08

最新評論