排序算法

Posted Lu_Lu的攻城路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法相关的知识,希望对你有一定的参考价值。

1、冒泡排序----效率较低

基本思想:首先依次比较相邻的两个数,如果不符合排序规则,则调换两个数的位置。这样一遍比较下来,能保证最大或最小的数排在最后一位,然后再对最后一位以外 的数重复前面的过程,直至全部排序完成。

eg:从小到大排列步骤:1.第一位与第二位比较,不符合互换位置,符合不换;2第二位与第三位比较不符合互换位置,符合不换;3第三位与第四位比较不符合互换位置,符合不换;4....知道比较到最后一位,此时最后一位已经变成最大的数,第二轮把最后一位除外再进行以上步骤,直到剩下最后一个位置,所有排序结束

//先定义一个交换函数,作用是交换两个位置的值
            function swap(myArray,p1,p2){
                var temp=myArray[p1];
                myArray[p1]=myArray[p2];
                myArray[p2]=temp;
            }
            //定义主函数
            function sort(myArry){
                var stop;
                for(var i=0;i<myArry.length-1;i++){
                    for(var j=0,stop=myArry.length-1-i;j<stop;j++){
                        if(myArry[j]>myArry[j+1]){
                            swap(myArry,j,j+1);
                        }
                    }
                }
                return myArry;
            }

2、选择排序

与冒泡排序相同的是也是一次对相邻的两个数进行比较,不同的是,选择排序是比较一轮完毕后直到找到最大值或最小值才把它放到正确位置,其他数的位置不变

平均时间复杂度:O(n2)

空间复杂度:O(1)  (用于交换和记录索引)

 

function swap(myArray,p1,p2){
                var temp=myArray[p1];
                myArray[p1]=myArray[p2];
                myArray[p2]=temp;
            }
            //定义主函数
            function selectionSort(myArry){
                var len=myArry.length;
                var min;
                for(var i=0;i<len;i++){
                    //将当前的位置设置为最小值;
                    min=i;
                    //检查数组其余部分是否更小
                    for(var j=i+1;j<len;j++){
                        if(myArry[j] < myArry[min]){
                            min=j;
                        }
                    }
                    if(i != min){
                        swap(myArry,i,min);
                    }
                }
                return myArry;
            }

3、插入排序---比前两者更有效率

基本思想:将数组分为已排序和未排序部分,一开始已排序部分只有一个元素,然后将它后面一个元素从未排序部分插入已排序部分,并将它与已排序部分的最后一个元素比较,符合规则则不变,不符合交换位置再与前一个元素比较,直到符合规则。从而已排序部分增加一个元素,未排序部分减少一个元素,以此类推,完成全部排序。

function insertionSort(myArry){
                var len=myArry.length;
                var value;    //当前比较的值
                var i;        //未排序部分的当前位置
                var j;        //已排序部分的当前位置
                for(var i=0;i<len;i++){
                    //储存当前位置的值
                    value=myArry[i];   
                    //当已排序部分的当前元素大于value,就将当前元素向后移一位,再将前一位与value比较
                    for(var j=i-1;j>-1&&myArry[j]>value;j--){
                        myArry[j+1]=myArry[j];
                        }
                    myArry[j+1]=value;
                }
                return myArry;
            }

4、合并排序——被广泛使用

基本思想:将数组拆开,分成n个只有一个元素的数组,然后不断的两两合并,直到全部排序完成。将两个已排序的数组合并,要比从头开始排序所有的元素来得快。

 function merge(left, right){
            var result  = [],
                il      = 0,
                ir      = 0;
            while (il < left.length && ir < right.length){
                if (left[il] < right[ir]){
                    result.push(left[il++]);
                } else {
                    result.push(right[ir++]);
                }
            }
            return result.concat(left.slice(il)).concat(right.slice(ir));
    }
            function mergeSort(myArray){

                    if (myArray.length < 2) {
                    return myArray;
        }
       var middle = Math.floor(myArray.length / 2),
        left    = myArray.slice(0, middle),
        right   = myArray.slice(middle),
        params = merge(mergeSort(left), mergeSort(right));
    
    // 在返回的数组头部,添加两个元素,第一个是0,第二个是返回的数组长度
           params.unshift(0, myArray.length);

 // splice用来替换数组元素,它接受多个参数,
 // 第一个是开始替换的位置,第二个是需要替换的个数,后面就是所有新加入的元素。
 // 因为splice不接受数组作为参数,所以采用apply的写法。
 // 这一句的意思就是原来的myArray数组替换成排序后的myArray
           myArray.splice.apply(myArray, params);
 // 返回排序后的数组
        return myArray;
}

5、快速排序——最快排序算法之一

基本思想:先确定一个支点,将所有小于支点的值放在该点的左侧,大于支点的值放在该点的右侧,然后对左右两侧不断重复这个过程,直到排序完成

function swap(myArray, firstIndex, secondIndex){
                    var temp = myArray[firstIndex];
                    myArray[firstIndex] = myArray[secondIndex];
                   myArray[secondIndex] = temp;
}
            function partition(myArray, left, right) {
                    var pivot   = myArray[Math.floor((right + left) / 2)],
                    i       = left,
                   j       = right;


                   while (i <= j) {

                        while (myArray[i] < pivot) {
                            i++;
                        }

                  while (myArray[j] > pivot) {
                           j--;            
                       }

                    if (i <= j) {
                        swap(myArray, i, j);
                            i++;
                            j--;
                    }
    }

    return i;
}
            function quickSort(myArray, left, right) {

                 if (myArray.length < 2) return myArray;
                
                 left = (typeof left !== "number" ? 0 : left);
                
                 right = (typeof right !== "number" ? myArray.length - 1 : right);
                
                 var index  = partition(myArray, left, right);
                
                  if (left < index - 1) {
                            quickSort(myArray, left, index - 1);
                     }
                
                  if (index < right) {
                            quickSort(myArray, index, right);
                      }
                
                  return myArray;

}

参考文献:

https://www.nczonline.net/blog/2009/05/26/computer-science-in-javascript-bubble-sort/

https://www.nczonline.net/blog/2012/09/17/computer-science-in-javascript-insertion-sort/

https://www.nczonline.net/blog/2012/09/17/computer-science-in-javascript-insertion-sort/

https://www.nczonline.net/blog/2012/10/02/computer-science-and-javascript-merge-sort/

https://www.nczonline.net/blog/2012/11/27/computer-science-in-javascript-quicksort/

以上是关于排序算法的主要内容,如果未能解决你的问题,请参考以下文章

算法排序之堆排序

快速排序-递归实现

从搜索文档中查找最小片段的算法?

在第6731次释放指针后双重免费或损坏

TimSort算法分析

以下代码片段的算法复杂度