JS 简单算法介绍

1、冒泡排序 - 依次比较相邻两元素,若前一元素大于后一元素则交换之,直至最后一个元素即为最大;然后重新从首元素开始重复同样的操作,直至倒数第二个元素即为次大元素;依次类推。如同水中的气泡,依次将最大或最小元素气泡浮出水面。
function bubbleSort(arr) {
    let len = arr.length;
    for(let i = 0; i < len; i ++) {
        for(let j = i + 1; j < len; j ++) {
            if(arr[j] < arr[i]) {
                [arr[i], arr[j]] = [arr[j], arr[i]];
            }
        }
    }
    return arr;
}
选择排序 - 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
function selectionSort(arr) {
    let len = arr.length;
    for(let i = 0; i < len; i ++) {
        let index = i;
        for(let j = i + 1; j < len; j ++) {
            if(arr[index] > arr[j]) {
                index = j;
            }
        }
        if(i !== index) {
            [arr[i], arr[index]] = [arr[index], arr[i]];
        }
    }
    return arr;
}
快速排序 - (基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
function quickSort(arr, left, right) {
    let principal = arr[Math.floor((left + right) / 2)], i = left, j = right;
    while (i <= j) {
        while (arr[i] < principal) {
            i ++;
        }
        while (arr[j] > principal) {
            j --;
        }
        if(i <= j) {
            [arr[i], arr[j]] = [arr[j], arr[i]];
            i ++;
            j --;
        }
    }
    if(left > i - 1) {
        return quickSort(arr, left, i - 1);
    }
    if(i < right) {
        return quickSort(arr, i, right);
    }
    return arr;
}
插入排序 - 基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。基本思想是:每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
// orderlyArr:已排序部分  disorderlyArr:未排序部分
function insertSort(orderlyArr, disorderlyArr) {
    if(disorderlyArr.length < 1) {
        return orderlyArr;
    }
    let target = disorderlyArr.shift(), len = orderlyArr.length, index = null;
    for(let i = 0; i < len; i ++) {
        if(target < orderlyArr[i]) {
            index = i;
            break;
        }
    }
    if((index || index === 0) && index < len) {
        for(let j = len - 1; j >= index; j --) {
            orderlyArr[j + 1] = orderlyArr[j];
        }
        orderlyArr[index] = target;
    }else {
        orderlyArr.push(target);
    }
    return insertSort(orderlyArr, disorderlyArr);
}
希尔排序 - 插入排序的改进版。为了减少数据的移动次数,在初始序列较大时取较大的步长,通常取序列长度的一半,此时只有两个元素比较,交换一次;之后步长依次减半直至步长为1,即为插入排序,由于此时序列已接近有序,故插入元素时数据移动的次数会相对较少,效率得到了提高。
function shellSort(arr) {
    for(let gap = Math.floor(arr.length / 2); gap > 0; gap = Math.floor(gap / 2)) {
        for(let i = gap; i < arr.length; i += gap) {
            let j = i;
            let temp = arr[j];
            for(; j > 0; j -= gap) {
                if(temp >= arr[j - gap]) {
                    break;
                }
                arr[j] = arr[j - gap];
            }
            arr[j] = temp;
        }
    }
    return arr;
}
桶排序 - 原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。

1、简单桶排序(数组中有几个数就生成几个桶)

function bucketSort(arr) {
    // 生成桶
    let bucketArr = [];
    for(let i = 0, len = arr.length; i < len; i ++) {
        bucketArr[arr[i]] = i;
    }
    const newArr = [];
    for(let i = 0, len = bucketArr.length; i < len; i ++) {
        if(bucketArr[i] !== undefined) {
            newArr.push(i);
        }
    }
    return newArr;
}

2、根据数组中最大值和最小值的差值来生成桶

function moreBucketSort(arr) {
    // 生成桶数
    const MIN = Math.min(...arr);
    const MAX = Math.max(...arr);
    const len = arr.length;
    let bucketNum = Math.floor((MAX - MIN) / len) + 1;
    // 生成桶
    let bucketArr = new Array(bucketNum).fill([]), newArr = [];
    // 元素放入桶中
    for(let i = 0; i < len; i ++) {
        const mulIndex = Math.floor((arr[i] - MIN) / len);
        bucketArr[mulIndex].push(arr[i]);
    }
    // 排序方式
    function bucketShellSort(arr) {
        for(let gap = Math.floor(arr.length / 2); gap > 0; gap = Math.floor(gap / 2)) {
            for(let i = gap; i < arr.length; i += gap) {
                let j = i;
                let temp = arr[j];
                for(; j > 0; j -= gap) {
                    if(temp >= arr[j - gap]) {
                        break;
                    }
                    arr[j] = arr[j - gap];
                }
                arr[j] = temp;
            }
        }
        return arr;
    }
    for(let i = 0, len = bucketArr.length; i < len; i ++) {
        bucketArr[i] = bucketShellSort(bucketArr[i]);
        newArr.push(...bucketArr[i]);
    }
    return newArr;
}
基数排序 - 桶排序的改进版,桶的大小固定为10,减少了内存空间的开销。首先,找出待排序列中得最大元素max,并依次按max的低位到高位对所有元素排序;桶元素10个元素的大小即为待排序数列元素对应数值为相等元素的个数,即每次遍历待排序数列,桶将其按对应数值位大小分为了10个层级,桶内元素值得和为待排序数列元素个数。
function radixSort(arr) {
    let MAX = Math.max(...arr), // 找出最大值
        num = MAX.toString().length, // 确定最大值的位数
        len = arr.length;
    let bucketArr = new Array(10);
    for(let m = 0; m < num; m ++) { // 按 个、十、百 依次比对
        let remainArr = [], newArr = [];
        for(let i = 0; i < 10; i ++) {
            bucketArr[i] = [];
        }
        for(let j = 0; j < len; j ++) {
            arr[j] = arr[j].toString();
            let idx = arr[j].length - m - 1;
            if(idx >= 0) {
                bucketArr[+arr[j][idx]].push(+arr[j]);
            }else {
                remainArr.push(+arr[j]);
            }
        }
        for(let i = 0; i < 10; i ++) {
            newArr.push(...bucketArr[i]);
        }
        arr = [...remainArr, ...newArr];
    }
    return arr;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值