js-常见排序算法

版权声明:本文为博主原创文章,若文章中有错误请联系博主改正,请不要恶意留言(不喜欢请绕道)。欢迎大家转载,转载时请注明原文地址:https://blog.csdn.net/qq_37674616/article/details/82315651

目录

一、选择排序

二、冒泡排序

三、插入排序

 1. 希尔排序

四、快速排序


我们衡量一个算法的指标包括:

  • 时间复杂度 (在排序过程中需要比较和交换的次数)

  • 空间复杂度 (在排序过程中需要的辅助存储空间)

  • 稳定性 (该算法的实现是否可以保证排序后相等元素的初始顺序,只要该算法存在一种实现可以保证这种特征,那么该算法就是稳定的)

  • 内部排序/外部排序 (在排序过程中数据元素是否完全在内存)

下表为各排序算法的性能标准:

一、选择排序

工作原理:初始时在未排序序列中找最小(最大)元素,放到序列的起始位置作为已排序序列;然后再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推。知道所有元素均排序完毕。
        

        /**
         * @Author   cc
         * @DateTime 2018-09-01
         * @param    {arr} 未排序数组
         * @return   {arr} 已排序数组
         * @description 选择排序
         */
            function sort(arr){
                var len=arr.length;
                //已排序序列的末尾
                for(var i=0;i<len;i++){
                    var min=i;
                    //待排序序列
                    for(var j=i+1;j<len;j++){
                         //从待排序序列中找到最小值
                        if(arr[j]<arr[min]){
                            min=j;
                        }
                    }
                    if(min!=i){
                        var temp=arr[i];
                        arr[i]=arr[min];
                        arr[min]=temp;
                    }
                }
                return arr;
            }
            //测试
            var arr=[1,4,35,3,2];
            sort(arr);
            console.log(arr); //[1,2,3,4,35]


        该排序算法不稳定,最差时间复杂度  o(n^2);最优时间复杂度  o(n^2);平均时间复杂度  o(n^2)

二、冒泡排序

冒泡排序是一种简单的排序算法,它重复走访要排序的数列,一次比较两个元素,如果他们的的顺序错误就把他们调换过来,知道没有元素再需要交换,排序完成。
           算法描述如下:   

比较相邻的元素。如果第一个比第二个大,就交换他们;
           对于每个相邻的元素重复相同的工作,知道最后一个元素,这样最后的元素会是最大的数
           针对所有元素重复以上的步骤,除了最后一个元素
           重复上面1~3步骤,知道排序结束

算法实现:

     /**
     * @Author   cc
     * @DateTime 2018-08-31
     * @param    {arr} 待数组
     * @return   {arr} 排好序的数组
     * @description 这是一个冒泡排序算法
     */
        function bubbleSort(arr) {
            var len = arr.length;
            for (var i = 0; i < len - 1; i++) { //比较的趟数,每次将最大值放到数组最后
                for (var j = 0; j < len - i - 1; j++) { //将相邻的两个元素,两两比较
                     if (arr[j]>arr[j+1]) { //元素交换值
                          var temp=arr[j];
                          arr[j]=arr[j+1];
                          arr[j+1]=temp;
                     }
                }
            }
            return arr;
        }
        var arr=[1,3,5,12,14,8,99];
        var result=bubbleSort(arr);
        console.log(result); //[1, 3, 5, 8, 12, 14, 99]

辅助草图:


        冒泡排序是稳定的排序算法,它的最差时间复杂度 o(n^2)即已排序数组;平均时间复杂度o(n^2),最优时间复杂度o(n)即在内部循环第一次运行时,使用一个旗标来表示该数组是不是已经是最小的了。
          

 将上面代码做如下改动
 

      function bubbleSort(arr) {
            var len = arr.length;
            for (var i = 0; i < len - 1; i++) { //比较的趟数,每次将最大值放到数组最后
                var k=1;  //标记是否有交换值
                for (var j = 0; j < len - i - 1&&k; j++) { //将相邻的两个元素,两两比较
                    var k=0;
                     if (arr[j]>arr[j+1]) { //元素交换值
                          var temp=arr[j];
                          arr[j]=arr[j+1];
                          arr[j+1]=temp;
                          k=1;
                     }
                     console.log('1');
                }
            }
            return arr;
        }

草图如下所示:

三、插入排序


         工作原理:是通过构建有序序列,对未排序数组,在已排序序列中从后向前扫描,找到相应位置并插入。
         算法描述:
             1. 从第一元素开始,该元素可以默认已经被排序
             2. 取出下一个元素,在已经排序序列中从后向前扫描
             3. 如果已排序的元素大于新元素,将该元素移到下一个位置
             4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
             5.将新元素插入到该位置
             6.重复2~5

                     /**
                     * @Author   cc
                     * @DateTime 2018-09-01
                     * @param    {arr} 待排序序列
                     * @return   {arr}  排好序序列
                     * @description 插入排序
                     */
                    function insertSort(arr) {
                        var len = arr.length;
                        var preIndex, current;
                        for (var i = 1; i < len; i++) {
                            preIndex = i - 1; //排好序的数组最后一个下标
                            current = arr[i]; //待排序的数值
                               //让待排序的值与排序好的数组值进行比较
                            while (preIndex >= 0 && arr[preIndex] > current) {
                                arr[preIndex + 1] = arr[preIndex];
                                preIndex--;
                            }
                            //待排序的数值大于等于排序好的值
                            arr[preIndex + 1] = current;
                        }
                        return arr;
                    }
                    var arr=[8, 3, 5, 9, , 7, 1, 2 ];
                    var result=insertSort(arr); //从小到大排序
                    console.log(result); //[1, 2, 3, 4, 5, 6, 7, 8]


                插入排序稳定,最差时间复杂度o(n^2)待排序列是降序序列;最优时间复杂度o(n)即待排序列是升序
                平均时间复杂度o(n^2)

 1. 希尔排序


            希尔排序:    是对插入排序的改进,它与插入不同之处它会优先比较距离较远的元素
            算法描述:
                 选择一个增量序列 t1,t2,...tk,其中ti>tj,tk=1;
                 按增量序列个数k,对序列进行k趟排序
                 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m的子序列,分别对各自表进行直接插入排序.当增量因子为一时,整个序列被分为一组,算法终止。

                     /**
                       * @Author   cc
                       * @DateTime 2018-09-01
                       * @param    {arr}
                       * @return   {arr} 已排序数组
                       * @description 希尔排序
                       */
                        function ShellSort(arr) {
                            var len = arr.length;
                            var temp, gap = 1;
                            while (gap <= len / 3) {
                                gap = gap * 3 + 1;  //生成增量
                            }
                            while (gap >= 1) {  //当分组变成成1时则排序完成

                                for (var i = gap; i < len; i++) {  //按增量循环数组
                                    temp = arr[i];
                                    //增量大于零且前面的数组的值大于后面数组的值则交换位置
                                    for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {
                                        arr[j + gap] = arr[j];
                                    }
                                    arr[j + gap] = temp;
                                }
                                console.log(gap);
                                gap = (gap - 1) / 3; //递减增量

                            }
                            return arr;
                        }
                        var arr = [5, 9, 2, 4,1,2,8,3,9,1];
                        var result = ShellSort(arr);
                        console.log(result);

  下图为增量为4时的内部数据交换图:

             

希尔排序稳定,时间复杂度为o(n^2),最优时间复杂度o(n)

四、快速排序


        该方法的基本思想:
            1. 从数列中取出一个数作为基数。
            2. 重新排序数列,所有元素比基准值小的放到基准值前,所有元素比基准值大的放到其后。
            3. 在对基准值左右区间,重复第二步,直到个区间只有一个数
        算法实现:

            /**
             * @Author   cc
             * @DateTime 2018-09-02
             * @param      arr   待排序数组
             * @param      left  数组第一个元素下标(0)
             * @param      right 数组最后一个元素下标
             * @return     arr   排好序的数组
             */
                function quickSort(arr,left,right){
                    if(left<right){
                        var i=left,j=right;
                        var x=arr[left]; //将基准数保存到 x 中
                        while (i<j) {
                            // 从右边向左边找小于x的数
                            while(i<j && arr[j]>=x){
                                j--;
                            }
                            if(i<j){
                                arr[i]=arr[j];
                                i++;
                            }
                            //从左边向右边找大于x的数
                            while(i<j && arr[i]< x){
                                i++;
                            }
                            if(i<j){
                                arr[j]=arr[i];
                                j--;
                            }
                        }
                        arr[i]=x;
                        console.log('i',i);
                        console.log(x);
                        console.log(arr);
                        quickSort(arr,left,i-1);
                        quickSort(arr,i+1,right);

                    }
                    return arr;
                }

                var arr=[3,2,45,12,4,3,12,4];
                console.log("原数组",arr);
                quickSort(arr,0,arr.length-1);
                console.log(arr); //[2, 3, 3, 4, 4, 12, 12, 45]

下图为上面算的内部数据描述:

猜你喜欢

转载自blog.csdn.net/qq_37674616/article/details/82315651
今日推荐