1. 程式人生 > 其它 >面試常用手寫防抖函式,節流函式,氣泡排序,快速排序

面試常用手寫防抖函式,節流函式,氣泡排序,快速排序

防抖:

防抖的特點是當事件快速連續觸發時,只會在最後事件觸發後執行一次對應函式。

比如輸入框的input事件,使用者的每次按鍵都會觸發input事件,但一般需要使用者輸入完後再執行相應的函式,此時就用到了防抖。

當input事件觸發時,生成一個定時器,延遲一段時間後再觸發對應函式。如果在延遲時間內再次觸發了事件,清除上一個定時器,

並生成一個新的定時器,使函式只會在最後一次事件觸發後執行。

程式碼解釋:

fn為最終要執行的函式,delay是延遲時間,單位毫秒。

使用閉包儲存變數 timer,如果timer有值,則清除上一個定時器,並生成一個新的定時器賦值給timer,

最終在定時器內執行函式fn。使用apply繫結this以及傳遞引數。

  function debounce(fn, delay) {     let timer = null     return function () {       if (timer) {         window.clearTimeout(timer)       }       timer = setTimeout(() => {         fn.apply(this, arguments)         timer = null       }, delay)     }   }    

節流:

節流的特點是當事件快速連續觸發時,一段時間內只會執行一次對應函式。

程式碼解釋:

fn為要執行的函式,delay是時間,單位毫秒。

使用閉包儲存變數 timer,如果timer為true,則執行一次fn函式,並將timer置為false,然後生成一個定時器在延遲delay時間後將timer置為true,

這樣當在延遲時間內再次觸發事件時,timer仍為false,函式並不會執行。

  function throttle (fn, delay){     var timer = true     return function (){       if(timer){         fn.apply(this,arguments)         timer = false         setTimeout(()=>{           timer = true         },delay)       }     }   }

氣泡排序:

簡單的排序演算法,效率不高

程式碼以及原理解釋:

假設陣列長度為N,氣泡排序對相鄰兩個數進行依次比較,並將大數放到後面。第一次比較時陣列的全部資料都需要進行比較,所以比較的下標範圍為:0 到 N-1。

通過這樣的一輪比較,可以確定最後一個數為最大的數,也就是說每一輪的比較只能確定一個數的正確位置。因此比較長度為 N 的陣列,共需要比較 N - 1 輪。

在第二輪比較時,不需要再比較最後一個數,因為已經確認最後一個是陣列中最大的數,所以本輪需要比較下標的範圍為:0 到 N - 1 - 1

在第三輪比較時,不需要再比較最後兩個數,所以需要比較下標的範圍為:0 到 N - 1 - 2次

所以其實每輪需要比較的下標範圍為: 0 到 N - 1 - i (i 為已經比較過的輪數)

function bubble(arr){  //控制比較輪次,一共 arr.length - 1 輪     for(let i = 0; i < arr.length - 1; i++){    //控制每輪需要比較的範圍       for(let j = 0; j < arr.length - 1 - i; j++){         if(arr[j] > arr[j+1]){           let current = arr[j]           arr[j] = arr[j + 1]            arr[j + 1]  = current         }       }     }     return arr  }

快速排序

原理:

(1)首先設定一個分界值,通過該分界值將陣列分成左右兩部分。 
(2)將大於或等於分界值的資料集中到陣列右邊,小於分界值的資料集中到陣列的左邊。此時,左邊部分中各元素都小於分界值,而右邊部分中各元素都大於或等於分界值。
(3)然後,左邊和右邊的資料可以獨立排序。對於左側的陣列資料,又可以取一個分界值,將該部分資料分成左右兩部分,同樣在左邊放置較小值,右邊放置較大值。右側的陣列資料也可以做類似處理。
(4)重複上述過程,可以看出,這是一個遞迴定義。通過遞迴將左側部分排好序後,再遞迴排好右側部分的順序。當左、右兩個部分各資料排序完成後,整個陣列的排序也就完成了

程式碼解釋:

示例程式碼採用了中間數當做分界值,小於分界值的放在left陣列,大於分界值的放在right陣列。

使用遞迴重複上面操作,陣列長度小於等於1時,會終止比較。

函式最後return了left陣列,分界值,right數組合並後的新陣列,也就是排序後的陣列。

function quickSort(arr) {     if (arr.length <= 1) {         return arr;     }     var pivotIndex = Math.floor(arr.length / 2);     var pivot = arr.splice(pivotIndex, 1)[0];     var left = [];     var right = [];     for (var i = 0; i < arr.length; i++) {         if (arr[i] < pivot) {             left.push(arr[i]);         } else {             right.push(arr[i]);         }     }     return quickSort(left).concat([pivot], quickSort(right)); };