JS-7種查找算法之順序查找、二分查找、插值查找、斐波那契查找


參考鏈接 https://www.cnblogs.com/yw09041432/p/5908444.html

1.順序查找

說明:順序查找適合於存儲結構為順序存儲或鏈接存儲的線性表。
基本思想:順序查找也稱為線形查找,屬於無序查找算法。從數據結構線形表的一端開始,順序掃描,依次將掃描到的結點關鍵字與給定值k相比較,若相等則表示查找成功;若掃描結束仍沒有找到關鍵字等於k的結點,表示查找失敗。
  復雜度分析: 
  查找成功時的平均查找長度為:(假設每個數據元素的概率相等) ASL = 1/n(1+2+3+…+n) = (n+1)/2 ;
  當查找不成功時,需要n+1次比較,時間復雜度為O(n);
  所以,順序查找的時間復雜度為O(n)。
 1 /**
 2  * 
 3  * @param {被查找數組} arr 
 4  * @param {查找的關鍵值} value 
 5  */
 6 function SequenceSearch(arr, value){
 7     for(let i = 0; i < arr.length; i++){
 8         if (arr[i] == value){
 9             return i;
10         }
11     }
12     return - 1;
13 }

 

 

2.二分查找

二分查找 也為折半查找
首先要找到一個中間值,通過與中間值比較,大的放又,小的放在左邊。再在兩邊中尋找中間值,持續以上操作,直到找到所在位置為止
找不到返回false

 1 // 遞歸
 2 function binarySearch(data, dest, start, end){
    if (start > end){ // 新增否則找不到進入死循環了
      return false;
    }
3 var end = end || data.length - 1; 4 var start = start || 0; 5 var m = Math.floor((start + end) / 2); 6 //直接命中 7 if (data[m] == dest){ 8 return m; 9 } 10 11 12 if (data[m] > dest){ // 放左 13 end = m - 1; 14 return binarySearch(data, dest, start, end); 15 }else{ // 放右 16 start = m + 1; 17 return binarySearch(data, dest, start, end); 18 } 19 return false; 20 } 21 22 // 非遞歸 用while 23 //代碼中的判斷條件必須是while (left <= right), 24 //否則的話判斷條件不完整,比如:array[3] = {1, 3, 5}; 25 //待查找的鍵為5,此時在(low < high)條件下就會找不到,因為low和high相等時,指向元素5,但是此時條件不成立,沒有進入while()中 26 27 function binarySearch2(data, dest){ 28 var end = data.length - 1; 29 var start = 0; 30 while(start <= end){ 31 var m = Math.floor((end + 1) / 2); 32 if(data[m] == dest){ 33 return m; 34 } 35 if (data[m] > dest){ 36 end = m - 1; 37 }else{ 38 start = m + 1; 39 } 40 } 41 return false 42 }

 

3. 插值查找
將二分查找的點改進為 mid=low+(key-a[low])/(a[high]-a[low])*(high-low)
基本思想:基於二分查找算法,將查找點的選擇改進為自適應選擇,可以提高查找效率。當然,差值查找也屬於有序查找。
  注:對於表長較大,而關鍵字分布又比較均勻的查找表來說,插值查找算法的平均性能比折半查找要好的多。反之,數組中如果分布非常不均勻,那么插值查找未必是很合適的選擇。
  復雜度分析:查找成功或者失敗的時間復雜度均為O(log2(log2n))。
 1 function InsertionSearch(arr, val, start, end){
 2     var end = end || data.length - 1;
 3     var start = start || 0;
 4 
 5     var mid = start + (val - arr[low]) / (arr[end] - arr[start]) * (end - start);
 6     if(arr[mid] == val){
 7         return mid;
 8     }
 9 
10     if(arr[mid] > val){
11         return InsertionSearch(arr, val, start, mid - 1);
12     }
13     else{
14         return InsertionSearch(arr, val, mid + 1, end);
15     }
16 }

 

4. 斐波那契查找
斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….(從第三個數開始,后邊每一個數都是前兩個數的和)
 1 // 斐波那契數組的實現
 2 function getNum1(index){
 3     if (index == 1 || index == 2){
 4         return 1;
 5     }else{
 6         return getNum(index - 1) + getNum(index - 2);
 7     }
 8 }
 9 
10 function getNum2(index){
11     if (index == 1 || index == 2){
12         return 1;
13     }else{
14         var one = 1; 
15         var two = 1;
16         for (var i = 3; i <= index; i++)
17         {
18             if (i == 3)
19             {
20                 one = 1;
21                 two = 1;
22             }
23             else
24             {
25                 var temp = one;
26                 one = two;
27                 two = temp + two;
28             }
29         }
30         return one + two
31     }
32 }
33 
34 function getNum3(index)
35 {
36     var F = [];
37     F[0]=0;
38     F[1]=1;
39     for(var i=2; i < index - 1; i++){
40         F[i]=F[i-1]+F[i-2];
41     }
42     return F[index];
43 }

 

顧名思義,該查找方法利用了斐波那契數列
該方法的主要思路為,先在斐波那契數列F中找到第k項,使其滿足,F[k]-1 > 有序數組的最大索引號 > F[k-1]-1,然后將數組擴充到長度為F[K]-1,並使擴充項的值都等於有序數組的最后一項。
分割點的索引為mid = low + F[K-1]-1,此時有序數組被mid划分為兩段,左段長度為F[K-1]-1,右段長度為F[k-2]-1。
若查找值大於mid值,則low等於mid+1,而k = k - 2;若查找值小於mid,則high = mid -1,k =k -1.
 1 function search(array, value){
 2     let low = 0, high = array.length - 1, n = array.length - 1;
 3     let mid, k = 0;
 4 
 5     // 構建一個長度大於array數組的斐波那契數組
 6     var F = [];
 7     F[0]=0;
 8     F[1]=1;
 9     for(var i=2; i < high + 5; i++){
10         F[i]=F[i-1]+F[i-2];
11     }
12 
13     while(high > F[k] - 1){ //尋找第k項
14         k++;
15     }
16 
17     for (let i=high; i<F[k]-1; i++){   //補全有序數組
18         array[i] = array[high];
19     }
20 
21     while (low <= high){
22         mid = low + F[k - 1] - 1;
23         if (array[mid] > value){
24             high = mid - 1;
25             k = k - 1; //長度縮減為 F[k-1] -1
26         }else if(array[mid] < value)
27         {
28             low = mid + 1;
29             k =  k - 2;         //長度縮減為 F[k-2] -1
30         }else{
31             if (mid <= n)  //相等則找到位置
32                 return mid;
33             else           //大於原始長度,則說明等於數組最后一項
34                 return n;
35         }
36     }
37     return -1;
38 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM