1. 程式人生 > >資料結構與演算法JavaScript描述讀書筆記3(檢索演算法)

資料結構與演算法JavaScript描述讀書筆記3(檢索演算法)

列表中查詢資料有兩種方法:順序查詢和二分查詢。順序查詢使用於元素隨機排列的列表;二分查詢適用於元素已排序的列表。二分查詢效率高,但是必須花費額外時間將列表中的元素排序

順序查詢

時間複雜度:O(n)

function seqSearch(arr,data){
    for(var i=0;i<arr.length;i++){
        if(arr[i] == data){
            return true;
        }
    }
    return false;
}

  //返回匹配到的位置資訊

function seqSearch(arr,data){
    for(var i=0;i<arr.length;i++){
        if(arr[i] == data){
            return i;
        }
    }
    return -1;
}

上述方法通過使用js的內建函式indexOf可以達到同樣的效果,如果沒有則返回-1,如果有則返回位置下標

使用自組織資料

原理:通過將頻繁查詢到的元素放在陣列的起始位置,減少查詢的次數,資料的查詢遵循‘80-20’原則,即80%的操作都是對20%的資料進行查詢,自組織的方法最終將這20%的資料移動到開始位置

//每查詢一次就將其向前移動一個位置,如果查詢次數夠多,則會移動到陣列的第一個為位置
function controlSearch(arr,data){
    for(var i=0;i<arr.length;i++){
        var temp;
        if(arr[i] == data){
            if(i>0){
                temp = arr[i-1];
                arr[i-1] = arr[i];
                arr[i] = temp;
            }
            return true;
        }
    }
    return false;
}

更好的自組織資料

原理:如果元素已經很接近起始位置,則不會移動,如果在20%之外,則將其移動到第一個位置

function controlSearch(arr,data){
    for(var i=0;i<arr.length;i++){
        var temp;
        if(arr[i] == data && i > (arr.length*0.2)){
            temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            return arr;
        }else if(arr[i] == data){
            return arr;
        }
    }
    return false;
}

二分查詢

演算法描述:

(1)將陣列的第一個位置設定為下邊界(0);

(2)將陣列最後一個元素所在位置設定為上邊界(陣列長度減1)

(3)如下邊界等於或小於上邊界,則做如下操作

         a. 將中點設定為(上邊界加下邊界)除以2

         b. 如果中點的元素小於查詢的值,則將下邊界設定為中點元素所在下標加 1。

         c. 如果中點的元素大於查詢的值,則將上邊界設定為中點元素所在下標減 1。

         d. 否則中點元素即為要查詢的資料,可以進行返回。

時間複雜度:O(logn)

function binSearch(arr,data){
    var left = 0;
    var right = arr.length-1;
    var mid;
    while (left<=right){
        mid = Math.floor((left+right)/2);
        if(arr[mid] < data){
            left = mid+1;
        }else if(arr[mid] > data){
            right = mid-1;
        }else{
            return mid;
        }
    }
    return -1;
}

計算重複次數

如果查詢的元素在陣列中重複出現,則找到的位置在這些位置的中間,可以根據這個特性可以計算重複值的個數

function count(arr,data){
    var count =0;
    var i = binSearch(arr,data);
    if(i > -1){
        count++;
        //向右查詢,如果不相等了就退出迴圈
        for(var j = i+1;j<arr.length;j++){
            if(arr[j] == data){
                count++;
            }else{
                break;
            }
        }
        //向左查詢,如果不相等了就退出迴圈
        for(var j = i-1;j>0;j--){
            if(arr[j] == data){
                count++;
            }else{
                break;
            }
        }
    }
    return count;
}