JS | 如何对一个数组进行排序?数组排序方法汇总

数组排序方法全解析

目录

一、冒泡排序

二、选择排序

三、插入排序

四、快速排序

五、堆排序

六、递并排序

七、希尔排序

八、计数排序


数组排序的核心方法包括多种自定义算法,如冒泡排序、选择排序、插入排序、快速排序和归并排序等,每种算法通过不同的比较和交换策略实现元素有序排列,适用于不同场景的数据规模与性能需求。

一、冒泡排序

排序规则:比较相邻元素,符合比较条件,交换位置较大的往后排,反复比较交换,直到所有数据都符合排序条件,得出排序效果,结束排序。

稳定性:稳定

排序动态示意:

代码实现:

var arr = [3,4,1,2,21,5,15,6,63];
function BubbleSort(ary){
    for(var i = 0;  i < ary.length - 1;  i++){
        for(var j = i + 1;  j < ary.length;  j++){
            var current = ary[i];
            if(current > ary[j]){
                var tmp = ary[j];
                ary[j] = current;
                ary[i] = tmp;
             }
         }
    }
   return ary;
}BubbleSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]

二、选择排序

排序规则:通过比较,选出最小的数放在第一位,然后在其余所有的数中选出最小的数排在第二位,以此类推,直到排序结束。

稳定性:不稳定

排序动态示意:

代码实现:

var arr = [3,4,1,2,21,5,15,6,63];
function SelectSort(ary){
    for(var i = 0; i < ary.length - 1; i++){
        for(var j = i + 1; j < ary.length; j++){
            if(ary[i] > ary[j]){
                var tmp = ary[i];
                ary[i] = ary[j];
                ary[j] = tmp;
            }
        }
    }
    return ary;
}SelectSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]

三、插入排序

排序规则:插入排序得比喻成斗地主,手里摸牌之后都是按照从小到大的顺序。每摸到一张牌就把他们插入到合适的位置,使得他们比后面小,比前面大或者相等。

稳定性:稳定

排序动态示意:

代码实现:

var arr = [3,4,1,2,21,5,15,6,63];
function InsertSort(ary){
    var temp;
    for (var i = 1; i < ary.length; i++) {
        for (var j = i-1; j >=0; j--) {
            if (ary[j+1] < ary[j]) {
                temp = ary[j+1];
                ary[j+1] = ary[j];
                ary[j] = temp;
            } else if (ary[j+1] >= ary[j]) {
                break;
            }
        }
    }
    return ary;
}
 
InsertSort(arr);  // [1, 2, 3, 4, 5, 6, 15, 21, 63]

四、快速排序

排序规则:从数组中找一个基准值,通过这个值挨个和数组中的值进行比较,大的放一边,小的放一边,然后进行合并后,在进行比较,反复直至结束。

稳定性:不稳定

排序动态示意:

代码实现:

var arr = [3,4,1,2,21,5,15,6,63];
var quickSort = function(ary) {
    if (ary.length <= 1) {
        return ary;
    }
    var pivotIndex = Math.floor(ary.length / 2);
    var pivot = ary.splice(pivotIndex, 1)[0];
    var left = [];
    var right = [];
 
    for (var i = 0; i < ary.length; i++) {
        if (ary[i] < pivot) {
            left.push(ary[i]);
        } else {
            right.push(ary[i]);
        }
    }
    return quickSort(left).concat([pivot], quickSort(right));
};
 
quickSort(arr);  // [1, 2, 3, 4, 5, 6, 15, 21, 63]

五、堆排序

排序规则:堆是一棵顺序存储的二叉树,堆分为最大堆和最小堆,最大堆父节点都大于子节点, 最小堆父节点都小于子节点,左子节点: 2*i +1 (i: 父节点index),右子节点: 2*i+2,从最后一个非叶子节点开始将堆进行小顶堆排序,每次拿出根节点,并和最后一个节点进行交换,重新进行堆的建立。

稳定性:不稳定

排序动态示意:

代码实现: 

var arr = [3,4,1,2,21,5,15,6,63];
function HeapSort(ary) {
     // 实现最大堆
     // start: 父节点, end: 循环深度
    function maxHeap(ary, start, end) {
        let parent = start, // 父节点
        son = parent*2 + 1, // 左子节点
        temp = null;
        // 规定循序最大深度
        while(son<=end) {
            // 如果存在右子节点, 并且判断右节点是否大于左节点
            if(son+1<=end && ary[son] < ary[son+1]) son++;
            if(ary[son] > ary[parent]) {
                temp = ary[son];
                ary[son] = ary[parent];
                ary[parent] = temp;
                parent = son;
                son = parent*2 +1;
            }else {
                return;
            }
        }
    }
    // 构建最大堆  ary.length/2-1: 表示最后一个父节点
    for(let i = ary.length/2-1; i>=0; i--) {
        maxHeap(ary, i, ary.length-1);
    }
    // 排序
    for(let i = ary.length-1; i>0; i--) {
        let temp = ary[0];
        ary[0] = ary[i];
        ary[i]= temp;
        // 剔除最后一个元素,并复原最大堆
        maxHeap(ary, 0, i-1);
    }
    return ary;
}
 
HeapSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]

六、递并排序

排序规则:将长的数组分解为短的数组,一直分到最后,单个单个数组比较,我们就认为,只有一个元素的数组是有序的。然后再逐个的合并。

稳定性:稳定

排序动态示意:

代码实现:

var arr = [3,4,1,2,21,5,15,6,63];
function MergeSort(ary) {  //采用自上而下的递归方法
    var len = ary.length;
    if(len < 2) {
        return ary;
    }
    var middle = Math.floor(len / 2),
        left = ary.slice(0, middle),
        right = ary.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}
 
function merge(left, right)
{
    var result = [];
 
    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }
 
    while (left.length)
        result.push(left.shift());
 
    while (right.length)
        result.push(right.shift());
 
    return result;
}
 
MergeSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]

七、希尔排序

排序规则:希尔排序是插入排序的一种更高效率的实现。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。

稳定性:不稳定

排序动态示意:

代码实现:

var arr = [3,4,1,2,21,5,15,6,63];
function ShellSort(ary) {
    var len = ary.length,
        temp,
        gap = 1;
    while(gap < len/3) {          //动态定义间隔序列
        gap =gap*3+1;
    }
    for (gap; gap > 0; gap = Math.floor(gap/3)) {
        for (var i = gap; i < len; i++) {
            temp = ary[i];
            for (var j = i-gap; j >= 0 && ary[j] > temp; j-=gap) {
                ary[j+gap] = ary[j];
            }
            ary[j+gap] = temp;
        }
    }
    return ary;
}
 
ShellSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]

八、计数排序

排序规则:

    1、找出待排序的数组中最大和最小的元素,然后建立一个数组C用于统计待排数组中最小元素到最大元素区间中每个元素出现次数;

  2、统计数组中每个值为i的元素出现的次数,存入数组C的第i项;

    3、对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);

    4、反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。

稳定性:稳定

排序动态示意:

代码实现:

var arr = [3,4,1,2,21,5,15,6,63];
function CountSort(ary){
    let obj={};
    for(let i=0; i<ary.length; i++){
        if(!obj[ary[i]]){
            obj[ary[i]]=1;
        }else{
            obj[ary[i]]++;
        }
    }
    let index=0;
    //遍历对象属性名,按顺序放回覆盖原数组
    for(let key in obj){
        while(obj[key]>0){
            ary[index]=Number(key);
            obj[key]--;
            index++
        }
    }
    return ary;
}
 
CountSort(arr); // [1, 2, 3, 4, 5, 6, 15, 21, 63]

▼算法选择与优化建议▼

‌性能考量‌:小规模数据可选插入排序;大规模数据优先快速排序或归并排序;内存受限时避免归并排序。‌‌

‌稳定性‌:冒泡、插入和归并排序是稳定的;选择排序和快速排序不稳定,可能改变相等元素的原始顺序。‌‌

‌实践提示‌:多数编程语言提供内置排序函数(如JavaScript的sort()),可直接调用;自定义实现时需注意边界条件和递归深度


▼参考资料▼

数组的几种排序方式 | 六种方法数组排序 | 几种常见的方法对数组进行排序

数组常用的几种排序方式 | 数组排序的五种方法 | 5种数组排序法 | 几种常见的排序算法总结

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值