boxmoe_header_banner_img

Hello! 欢迎来到盒子萌!

加载中

文章导读

01算法


avatar
Jack 2023年 5月 1日 371

JavaScript算法

一、算法复杂度

给定一个或多个已知值,通过一系列的运算输出所需结果的过程,叫做算法。一个需求可能可以通过多种算法来实现,学习算法让我们了解怎样的算法效率更高更快,从而让我们针对某个需求做出最合适的选择。作为一名前端攻城狮,算法可能目前离你很远,但是如果你想在编程的路上走的更远一些,或涉猎到更多的数据逻辑,算法对你的帮助很大。所以想成为一名高端的开发者,算法是必须要学习的。

讨论一个算法的好坏,有最主要的两个方面:该算法所需时间-时间复杂度,该算法占用空间(内存)-空间复杂度。耗时短占用低肯定是最优选择,而往往我们需要在两者中找到一个平衡点。作为一名程序开发者,大多数情况下,时间复杂度比空间复杂度的影响更大一些,能做的改良和优化也更多,所以一般如果不做特别说明,我们在讨论算法复杂度的时候都是指时间复杂度

1. 时间复杂度

一个算法所需要的时间需要具体上机运行才知道,很显然不可能每个都验证一遍再做选择。我们可以对算法耗时进行合理的预测。

一个算法中语句的执行次数我们叫做时间频度,记做T(n)n表示问题规模,n增大T(n)也随之增大。而我们预估算法的效率,就是对T(n)的变化趋势进行分析,为了方便分析,我们需要简化一下T(n)函数,所以我们引入时间复杂度的概念:若有某个辅助函数 f(n),使得当n趋近与无穷大时,T(n)/f(n) 的极限值为不等于0的常数,则称 f(n) 是 T(n)的同数量级函数,记做 T(n) = O( f(n) )O( f(n) )就是时间复杂度的表示法。

总结一下:用O( f(n) )来表示算法时间复杂度。

2. 复杂度计算举例

理论上,我们对 O( f(n) ) 中的 f(n) 没有写法限制,但是因为我们关注的是随 n 增大复杂度的变化趋势,所以各常数项和系数我们是直接省略不做考虑的。

let a = 1;
let b = 2;
console.log(a+b);
//O(1)

let z = 0;
for(let i=0;i

二、js中常用算法

1.数组整数字去重

//基础写法
function fn(arr){
    let newArr = [...arr];
    for(let i=newArr.length-1;i>=0;i--){
        for(let j=i-1;j>=0;j--){
            if( newArr[i] === newArr[j] ){
                newArr.splice(j,1);
                i --;
            }
        }
    }
    return newArr;
}
//O(n^2)

//优化算法复杂度
function fn(arr){
    let tmp = {};
    let newArr = [];

    for(let i=0,length=arr.length;i

注意:Set结构帮助我们实现去重,不代表复杂度为 1 ,因为内部对数组已经进行了遍历,相当于做了封装。

2. 判断回文

数据结构课程中使用栈结构实现了回文,此处我们讨论一下复杂度。

3. 寻找重复最多字符

let str = "abfsafsafghjiq15445454";

function fn(str){
    let length = str.length;
    let tmp = {};

    for(let i=0;i max ){
            k = [key];
            max = value;
        }else if( value === max ){
            k.push(key);
        }
    }
    return k;
}

console.log(fn(str));
//O(n)

三、排序算法

1. 冒泡排序

动图演示(动图来源visualgo (opens new window)):img

function bubbleSort (arr) {
    let len = arr.length;
    //要进行多少轮排序
    for(let i = 0; i < len-1; i++) {
        //每一轮,相邻两位进行比较,大的放后面
        for(let j = 0; j < len-1-i ; j++) {
            if( arr[j] > arr[j+1] ){
                swap(arr,j,j+1);
            }
        }
    }
}
function swap(arr,i,j){
    let tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

2. 选择排序

动图演示(动图来源visualgo (opens new window)):img

function selectionSort(arr){
    let len = arr.length;
    let minIndex;
    for(let i = 0; i < len ; i++) {
        minIndex = i;
        for(let j = i+1; j < len ; j++) {
            if( arr[j] < arr[minIndex] ){
                minIndex = j;
            }
        }
        swap(arr,i,minIndex);
    }
}
function swap(arr,i,j){
    let tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

3. 插入排序

动图演示(动图来源visualgo (opens new window)):img

function insertSort (arr) {
    let len = arr.length;
    let j;
    let current;
    for(let i = 1; i < len; i++) {
        j = i - 1;
        current = arr[i];
        while(j >= 0 && arr[j] > current) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = current;
    }
}

4. 快速排序(分治思想)

快速排序是使用分治思想的典型代表。选择一个基准元素,把数组分成左右两部分,左边比基准小,右边比基准大,分别对左右部分递归调用快速排序。

function quickSort(arr){
    if(arr.length <= 1){
        return arr;
    }
    let pivot = arr[0];
    let left = [];
    let right = [];

    for(let i=1;i

平均时间复杂度 O(n log n),最坏情况 O(n²),空间复杂度 O(log n)。

5. 归并排序(分治思想)

归并排序也是分治思想,通过递归分割数组并合并排序好的子数组。

function mergeSort(arr){
    if(arr.length <= 1) return arr;

    let mid = Math.floor(arr.length / 2);
    let left = arr.slice(0, mid);
    let right = arr.slice(mid);

    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right){
    let result = [];
    let i=0, j=0;

    while(i < left.length && j < right.length){
        if(left[i] <= right[j]){
            result.push(left[i++]);
        }else{
            result.push(right[j++]);
        }
    }

    return result.concat(left.slice(i)).concat(right.slice(j));
}

时间复杂度稳定为 O(n log n),空间复杂度为 O(n)。

四、总结

  • 算法是为了解决问题而设计的计算步骤;
  • 时间复杂度表示算法执行时间随问题规模变化的趋势;
  • 常见时间复杂度有 O(1)、O(n)、O(n²)、O(log n)、O(n log n)、O(2^n)等;
  • 数组去重、字符串处理、排序等是JS中常用的基础算法;
  • 排序算法多样,冒泡、选择、插入、快速、归并各有优缺点,选择时根据实际需求。


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码