前端常用的查找和排序算法等必会知识点

栏目: 编程工具 · 发布时间: 5年前

function insertNumber(arr, x) {
    
    //查找到第一个大于x的数字
    let b = newArr.find(e => e > x);
    
    
    if (b === undefined) { 
        // 如果b不存在,证明x是最大的数字,push到数组尾部
        newArr.push(x);
        
    } else {
    
        //获取b的index,把新的数字插入到b的位置
        let bIndex = newArr.indexOf(b)
        newArr.splice(bIndex, 0, x)
    }
    
    return arr;

}

复制代码

两个有序数组合并成一个新的有序数组

  • 和插入一样, 第一个解构,对第二个数组进行遍历循环插入到第一个数组
function insert_some_numbers(arr1, arr2) {
    //创建新数组,并结构第一个数组
    var newArr = [...arr1];
    
    for (var i = 0; i < arr2.length; i++) {
        //获取第二个数组中的每一位
        x = arr2[i];
        
        //在新解构的数组中查找第一个比他大的数组
        let b = newArr.find(e => e > x);
        
        //获取到这个数字的索引并插入到他的前面
        let bindex = newArr.indexOf(b)
        newArr.splice(bindex === -1 ? newArr.length : bindex, 0, x)
    }
    return newArr;
}
let arr1 = [1, 2, 3, 4, 5, 6, 8, 9];
console.log(insert_some_numbers(arr1, [1, 2, 3]));
复制代码

二分查找

  • 最大查找次数 Math.ceil(Math.log2(arr.length))
function binarySearch(arr, x) {
    var left = 0; //左边界
    var right = arr.length - 1; //右边界
    var guess;  // 游标, 中间索引去小数点

    while (left <= right) { // 左侧边界小于右侧边界才执行
    
        guess = ((left + right) / 2) | 0;  //游标索引, 中间索引去小数点
        
        if (arr[guess] === x) return guess // 当游标索引就是查找的X的话,返回游标索引
        
        else if (arr[guess] > x) right = guess - 1 // 游标索引位 大于 x , 右边界移动到guess之前。
        
        else left = guess + 1 // 游标索引位 小于 x , 右边界移动到guess之后。
    }
    
    return -1; //未查找到
}


var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(
    binarySearch(arr, 5) 
)
复制代码

有序数组插入新数字

  • 模拟一个空位置循环比较,
  • 从数组尾部向前比较,前面的那一位比x大,比x大的那个数字索引+1,
  • 再跟前面的一位作比较,如果比X小, p+1位索引就被x占了
function insert_number_3(arr, x) {
    //p是下一个待比较元素的索引
    //p-1是空位
    //p不能小于0, 当P小于0代表, x是最小的
    let p = arr.length - 1;
    while (p >= 0 && arr[p] > x) {
        arr[p + 1] = arr[p];
        p--;
    }
    arr[p + 1] = x;
}
let arr1 = [1, 2, 3, 4, 5, 6, 8, 9];
insert_number_3(arr1, 6)
console.log(arr1)
复制代码

插入排序

  • 性能最差
  • n^2/2 - n/2 次比较
  • 从数组的第1索引位置,逐次向前比较
  • 比较次数 1 + 2 + 3 + ··· + arr.length 次
function insertion_sort(arr) {
    //第一位不用去作比较,只有一位的数组可以看作为有序数组
    for (var i = 1; i < arr.length; i++) {
        insert(arr, i, arr[i]);
    }
}

function insert(arr, i, x) {
    let p = i - 1; // p 作为被首先比较的元素
    // arr[i] 也就是 x  是待插入的元素
    while (p >= 0 && arr[p] > x) {
        // 当待插入的元素
        arr[p + 1] = arr[p];
        p--;
    }
    arr[p + 1] = x;
}
复制代码

冒泡排序

  • 先找出最大的,再找出最小的
  • 性能最差
  • 排序次数: arr.length的等差数列求和次 -> n**n/2 -n/2 次
function bubble_sort(arr) {
    //值交换函数
    function swap(arr, x, j) {
        var temp = arr[x];
        arr[x] = arr[j];
        arr[j] = temp;
    }
    
    //先找出最大的,再找出最小的
    for (let i = arr.length - 1; i >= 1; i--) {
        //从1开始,每一次都和前一位作比较。
        for (let j = 1; j <= i; j++) {
            arr[j] < arr[j - 1] && swap(arr, j-1, j)
        }
    }
}

const arr2 = [91, 60, 96, 9, 30, 20, 31, 77, 81, 24];
bubble_sort(arr2)
console.log(arr2);
复制代码

深度克隆

function deepClone2(origin, target) {
    var target = target || ((origin instanceof Array) ? [] : {});

    for (var prop in origin) {
        if (origin.hasOwnProperty(prop)) {
            if (typeof origin[prop] == 'object') {
                if (Object.prototype.toString.call(origin[prop]) === '[object Array]') {
                    target[prop] = [];
                } else {
                    target[prop] = {};
                }
                deepClone2(origin[prop], target[prop]);
            } else {
                target[prop] = origin[prop]
            }
        }
    }
    return target;
}
复制代码

合并排序

//将数组分成两个数组, 
// 索引 [a,b) 和 [b,c)

//合并函数部分,
function merge(arr, a, b, c) {
    // 此时arr1 和 arr2 是 两个有序数组
    let arr1 = arr.slice(a, b);
    let arr2 = arr.slice(b, c);

    //在两个数组后面布置哨兵
    arr1.push(Infinity);
    arr2.push(Infinity);
    //设置两个数组的比较位置的索引的游标索引
    // 如果这个数字被赋值,则索引+1
    var i = 0, j = 0;
    //循环给arr赋值
    for (let k = a; k < c; k++) {
        //k : 下一个写入位置
        //i : arr1中的回写位置
        //j :  arr2中的回写位置
        arr[k] = arr1[i] < arr2[j] ? arr1[i++] : arr2[j++];
    }
}

function mergeSort(arr, a, c) {
    //判断数组长度是否为1
    if (c - a < 2) { return };
    const b = Math.ceil((a + c) / 2);
    //左侧部分递归
    mergeSort(arr, a, b);
    //右侧部分递归
    mergeSort(arr, b, c);
    //执行拼接
    merge(arr, a, b, c);
}

// 把数组拆成一个,一个的数组, 在执行拼接
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Metasploit渗透测试魔鬼训练营

Metasploit渗透测试魔鬼训练营

诸葛建伟、陈力波、田繁、孙松柏、等 / 机械工业出版社 / 2013-9-1 / 89.00元

首本中文原创Metasploit渗透测试著作,国内信息安全领域布道者和资深Metasploit渗透测试专家领衔撰写,极具权威性。以实践为导向,既详细讲解了Metasploit渗透测试的技术、流程、方法和技巧,又深刻阐释了渗透测试平台背后蕴含的思想。 本书是Metasploit渗透测试领域难得的经典佳作,由国内信息安全领域的资深Metasploit渗透测试专家领衔撰写。内容系统、广泛、有深度,......一起来看看 《Metasploit渗透测试魔鬼训练营》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具