JS数据结构之排序算法(代码解释)

摘要

通过JavaScript实现的排序算法

数组构造

基本数组函数及方法构造

 function ArrayList() {
            //属性
            this.items = [],
                //插入数据
                ArrayList.prototype.insert = function(data) {
                    this.items.push(data);
                }

            //打印数组
            ArrayList.prototype.toString = function() {
                console.log(this.items.join("-"));
            }

            //交换函数
            ArrayList.prototype.swap = function(i, j) {
                var temp = this.items[i];
                this.items[i] = this.items[j];
                this.items[j] = temp;
            }
}

一、简单排序

1.冒泡排序

代码及详解:

图解:在这里插入图片描述

 //排序算法
            //1.冒泡排序(时间复杂度O(n^2))
            ArrayList.prototype.bubbleSort = function() {
                //原理分析:重复从头开始两两比较,将大的值置后,每次比较次数随着每次选出的最大值个数减少
                //第1次 i = 0 ,两两比较,需要比较到 i = length-2 
                //第2次 i = 0 ,两两比较,需要比较到 i = length-3
                //第3次 i = 0 ,两两比较,需要比较到 i = length-4
                //第n次 i = 0 ,两两比较,需要比较到 i = length-n-1 
                //最后一次 i = 0 ,两两比较,需要比较到 i = 1 > 0
                for (var j = this.items.length - 1; j > 0; j--) {
                    for (var i = 0; i < j; i++) {
                        if (this.items[i] > this.items[i + 1]) {
                            this.swap(i, i + 1);
                        }
                    }
                }
            }

2.选择排序

代码及详解:

图解:

在这里插入图片描述

 //2.选择排序(时间复杂度O(n^2))
            //在冒泡排序的基础上改进交换次数
            ArrayList.prototype.selectionSort = function() {
                //原理分析:重复比较选出最小的元素,将每次选出的最小元素交换至已排序数组的最后(与未排序数组的第一个元素交换),直至未排序元素个数等于1个
                //第1次 i = 0,循环比较至i = length - 1,选出最小的值与i = 0 的元素交换
                //第2次 i = 1,循环比较至i = length - 1,选出最小的值与i = 1 的元素交换
                //第3次 i = 2,循环比较至i = length - 1,选出最小的值与i = 2 的元素交换
                //第n次 i = n-1,循环比较至i = length - 1,选出最小的值与i = n 的元素交换
                //最后一次 i = length - 2 与i = length - 1比较
                for (var j = 0; j < this.items.length - 1; j++) {
                    var min = j;
                    for (var i = min + 1; i < this.items.length; i++) {
                        if (this.items[i] < this.items[min]) {
                            min = i;
                        }
                    }
                    this.swap(min, j);
                }


            }

3.插入排序

代码及详解:

图解:
在这里插入图片描述

 //3.插入排序O(n^2)
            ArrayList.prototype.insertSort = function() {
                //原理分析:将第一个元素看成是有序的部分,从第二个元素开始取出元素与有序部分的元素从后往前比较,将较大的元素往后移,直至找到相应位置
                //第1次  i = 1,与有序部分(数组的第一个元素)比较,若较小,则将较大部分往后移,若较大则,直接插入末尾(不需要移动)
                //第2次  i = 2,与有序部分(数组的第一、二个元素)比较,若较小,则将较大部分往后移
                //第n次  i = n,与有序部分(数组的前n个元素)比较,若较小,则将较大部分往后移
                for (var i = 1; i < this.items.length; i++) { //将第一个元素看成有序部分,从第二个元素开始对有序部分进行比较
                    var temp = this.items[i];
                    for (var j = i - 1; j >= 0; j--) { //从有序部分从后往前与插入元素进行比较
                        if (this.items[j] > temp) {
                            this.items[j + 1] = this.items[j];
                        } else {
                            break;
                        }
                    }
                    this.items[j + 1] = temp;


                }
            }

二、高级排序

1.希尔排序

个人建议:先深刻理解插入排序,再学希尔排序

代码及详解:

图解:
在这里插入图片描述

 //4.希尔排序
            ArrayList.prototype.shellSort = function() {
                //原理分析:对原数组进行间隔不断缩小的分组插入排序(对插入排序的改进版)
                //第1次:对数组进行间隔length/2的分组插入排序 
                //解释:将每隔length/2的所有数组元素看成一个数组进行插入排序
                //注意:书写代码时应注意下标增量应该是length/2
                //第2次:对数组进行间隔length/4的分组插入排序
                //第2次:对数组进行间隔length/4的分组插入排序
                //第n次:对数组进行间隔length/2^n的分组插入排序
                //最后一次:对数组进行间隔1的分组排序

                //获取数组长度
                var length = this.items.length;
                //设置初始间隔
                var gap = Math.floor(length / 2);
                while (gap >= 1) { //间隔大于1时不断进行分组插入排序
                    for (var i = gap; i < length; i++) { //第一个间隔的远古三为所有分组的第一个元素,默认为有序的部分
                        var temp = this.items[i];
                        for (var j = i - gap; j >= 0; j = j - gap) {
                            //循环对分为一组的元素进行类似插入排序的操作(判断前面的元素是否比后面的大,如果是,前面的元素往后移动,接着继续往前比较,直至大于前面的元素,插入该元素的后面)
                            if (this.items[j] > temp) {
                                this.items[j + gap] = this.items[j];
                            } else {
                                break;
                            }
                        }
                        this.items[j + gap] = temp;
                    }
                    gap = Math.floor(gap / 2);
                }
            }

2.快速排序

代码及详解:

图解:
在这里插入图片描述

  //5.快速排序
            // 原理:
            //1.先从数列中取出一个数作为基准数。
            //2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
            //3.再对左右区间重复第二步,直到各区间只有一个数。  
            /*取第一个作为参考值,从(end)后找小于参考值的数,
            填在参考值的坑(填坑后原来的值的位置相当于一个坑),再从(start)头开始找大于参考值的数,
            填上一个坑,重复填坑,直至start=end时,此时坑的位置就是参考值的位置,参考值左边是小于参考值的数,右边是大于参考值的数
            再递归对两边的数组也进行同样的操作,直至两边的数组只有一个元素*/
            ArrayList.prototype.fastSort = function(start, end) {
                if (start < end) {
                    //如果start不小于end则递归结束
                    var i = start;
                    var j = end;
                    var temp = this.items[start];
                    while (i < j) {
                        while (i < j && this.items[j] >= temp) {
                            //从后找出小于参考值的数
                            j--;
                        }
                        if (i < j) {
                            //若找到,则填坑
                            this.items[i++] = this.items[j];
                        }
                        while (i < j && this.items[i] < temp) {
                            i++;
                        }
                        if (i < j) {
                            this.items[j--] = this.items[i];
                        }
                    }
                    this.items[i] = temp;
                    this.fastSort(start, i - 1);
                    this.fastSort(i + 1, end);
                }
            }

总结

此文章皆是本人理解手打的代码,希望能帮到需要的人,需要改进的地方欢迎各位大佬点评

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值