检索算法 -- 数据结构与算法的javascript描述 第13章

检索算法-如何在列表中查找特定的值。

顺序查找

从列表的第一个元素开始对列表元素逐个进行判断,直到找到了想要的结果,它属于暴力查找技巧的一种,在执行查找时可能会访问到数据结构里的所有元素。

代码:

//版本1
function seqSearch1(arr,data){
    //顺序查找
    //就是循环查找 挨着一个一个查找
    //v1 返回布尔值
    for (var i = 0; i < arr.length; ++i) {
        if (arr[i] == data) {
            return true;
        }
    }
    return false;
}

//版本二   返回下标或者-1
function seqSearch2(arr,data){
    for (var i = 0; i < arr.length; ++i) {
        if (arr[i] == data) {
            return i;
        }
    }
    return -1;
}

查找最大值和最小值

function findMin(arr){
    var min = arr[0]
    for(var i=0;i<arr.length;++i){
        min = Math.min(arr[i],min)
    }
    return min;
}
function findMax(arr){
    var min = arr[0]
    for(var i=0;i<arr.length;++i){
        min = Math.max(arr[i],min)
    }
    return min;
}

未排序查找

对于未排序的数据集来说,当被查找的数据位于数据集的起始位置时,查找是最快、最成功的

问题所在:

数据未排序的情况下,你要找一个数据就需要耗费较多时间去查找。
对于未排序的数据集来说,当被查找的数据位于数据集的起始位置时,查找是最快、最成功的。
这一想法 参照与 82理论,百分之八十的查找都是在找百分之二十的那些数据
我们将被查找的元素不断的放到数据起始位置,来改变数组的排序。
使用这个方法之后,查找最频繁的元素最终会移动到数据集的起始位置,

代码:

function seqSearch3(arr,data){
    for (var i = 0; i < arr.length; ++i) {
        if (arr[i] == data) {
            if (i > 0) {
                //改变元素位置。
                swap(arr,i,i-1);
            }
            return true;
        }
    }
    return false;
}
function swap(arr, index, index1) {
    var temp = arr[index];
    arr[index] = arr[index1];
    arr[index1] = temp;
}

这个版本 会不断修改数剧位置,但是有个问题,有时候数据已经在前几个位置了,但是还会被放到前面。
我们将判断该元素是否处于 20%的位置,如果处于就不调换位置。

升级版:

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

二分查找

二分查找是基于有序数据的。 比顺序查找效率要高很多。

基本思路:

开始猜一个数字,将数据中间的值跟查找值比较: 会有3种情况==》猜大了 、猜小了、猜对了。如果是猜大了或者猜小了,那么可以重复对数据做处理 重新查找中间值,再做判断。

代码:

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

以上就是我们的二分查找方式,不过呢,假如一堆有序数据中又多个相同的值,我们该如何得知它有几个同类呢?

增加统计方法:

//如果一个数据 34 在数组中有多个 34,34,34 那么2分发会找到中间的那个,那么无法准确告知我们有3个34
//我们需要一个统计方法 来告知有几个相同的查找值
function binCount(arr,data){
    var count = 0;
    var pos = binSearch(arr,data)
    if(pos>-1){
        ++count;
        for(var i=pos-1;i>0;--i){
            if(arr[i]==data){
                ++count;
            }else{
                break;
            }
        }
        for(var i=pos+1;i<arr.length;++i){
            if(arr[i]==data){
                ++count;
            }else{
                break;
            }
        }
    }
    return count;
}

测试:

//生成数据的方法
function createArr(){
    var nums = [];
    for (var i = 0; i < 100; ++i) {
        nums[i] = Math.floor(Math.random() * 101);
    }
    return nums;
}
var nums = createArr();
 
 //二分查找需要数据排序
nums.sort(function(n1,n2){
    return n1-n2;
})
var n=46
console.log("二分:"+ binCount(nums,46)+"个数据被找到")
原文地址:https://www.cnblogs.com/iyueyao/p/4161234.html