12种常用排序算法

2017-05-09  本文已影响0人  biubiu15

本文仅作为个人学习排序算法的参考笔记,若想详细了解学习,请前往 http://blog.csdn.net/han_xiaoyang/article/details/12163251

tip:
  • 文章中涉及的所有排序均为升序

插入排序算法

void insertionSort(int arr[]) 
{
    for(int i = 1; i < arr.length; i++)
    {
        int j = i - 1;
        int temp = arr[i];
        while((j >= 0) && (arr[j] > temp))
        {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = temp;
    }
}

二分插入排序算法

void BinInsertSort(int arr[])
{
    for(int i = 1; i < arr.length; i++)
    {
        int left = 0;
        int right = i - 1;
        int temp = arr[i];
        while (left <= right) 
        {
            int middle = (left +right) / 2;
            if(arr[middle] > temp)
            {
                right = middle - 1;
            }
            else 
            {
                left = middle + 1;
            }
        }

        for(int j = i - 1; j >= left; j--)
        {
            arr[j + 1] = arr[j];
        }
        arr[left] = temp;
    }
}
小结:

希尔排序

void shellSort(int arr[]) 
{
    int gap = arr.length / 2; //在此增量取数组长度/2
    while(gap > 0)
    {
        for(int i = 0; i < gap; i++)
        {
            int j = i + gap;
            int temp = arr[j];
            while((temp < arr[i]) && (j < arr.length))
            {
                arr[j] = arr[i];
                j += gap;
            }
            arr[j] = temp;
        }
        gap /= 2;
    }
}

选择排序

复杂度
最差时间复杂度 О(n²)
最优时间复杂度 О(n²)
平均时间复杂度 О(n²)
最差空间复杂度 О(n) total, O(1)
void selectSort(int arr[]) 
{
    int length = arr.length;
    for(int i = 0; i < length; i++)
    {
        int min = arr[i];
        int index = i;
        int j = i + 1;
        while(j < length)
        {
            if(min > arr[j])
            {
                min = arr[j];
                index = j;
            }
            j++;
        }
        arr[index] = arr[i];
        arr[i] = min;
    }
}

快速排序

复杂度
最差时间复杂度 О(n^2)
最优时间复杂度 O(n log n)
平均时间复杂度 O(n log n)
最差空间复杂度 根据实现的方式不同而不同
  1. 从数列中挑出一个元素,称为 "基准"(pivot);
  2. 排序数组,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
function quickSort(first, end, array) {
        var key = array[first];//默认选择第一个为pivot
        var i = first;
        var j = end;
        if (first > end) {
            while (i < j) {
                /**
                 * 以 23 7 36 8 15 9 为例, 第一遍基准为23
                 */

                // 从数组最右边开始遍历, 如果比基准大, 则比较下一个; 如果比基准小, 则赋值到基准的位置
                while (array[j] > key && j > i) {
                    j--;
                }
                if (i < j) {
                    array[i++] = array[j];
                    // 赋值后, 数组排列为9 7 36 8 15 9  i=1 j=5
                    // 数组中有两个相同的数, 其中赋值到基准位置的数才是其正确位置, j位置上的则是可被替换的
                }

                // 从数组最左边开始遍历, 如果比基准小, 则比较下一个; 如果比基准大, 则赋值到j的位置
                while (array[i] < key && j > i) {
                    i++;
                }

                if (i < j) {
                    array[j--] = array[i];
                    // 赋值后, 数组排列为9 7 36 8 15 36  i=2 j=4
                    // 数组中有两个相同的数, 其中赋值到j位置的数才是其正确位置, i位置上的则是可被替换的
                }
                array[i] = key;
                // 将基准赋值到i位置 数组排序为9 7 23 8 15 36 
                // i=2 j=4 在进行一次以23为基准的循环
                // 得到 9 7 15 8 23 36  保证在23前的数都比23小, 在23后的数都比23大. 则以23为基准的排序结束, 跳出循环
            }

            quickSort(0, i - 1, array);
            quickSort(i + 1, array.length - 1, array);
        }
    }
上一篇下一篇

猜你喜欢

热点阅读