数据结构(十三)排序

排序

排序分为内排序和外排序

内排序三个重要指标

 
 
  

排序分类

冒泡排序

在升序的情况下,相邻的两个元素比较,较大的交换到前面
时间复杂度 O(n²)
 

简单选择排序

在升序的情况下,每一次遍历都找到该次遍历最大值
时间复杂度O(n²)
性能略优于冒泡
 

直接插入排序

将一个元素插入到已经排好序的有序表中
时间复杂度O(n²)
性能略优于简单选择排序
 

希尔排序

先获得一个基本有序的数列
在升序的情况下,第一次遍历先把较大的放前面,较小的放后面
时间复杂度O(n3/2次方)
 

堆排序

对简单选择排序的改进
时间复杂度O(nlogn)
不适合待排序序列较少的情况
 

归并排序

时间复杂度O(nlogn)
空间复杂度O(n+logn)
高效稳定的排序方法,比较占内存
 

快速排序

定义
时间复杂度
平均O(nlogn)
最坏O(n²)
分而治之的思想是多么的重要,作为最重要的排序算法,快速排序的代码实现如下
 /**
     * 递归排序,每次都把一个数组分成两个数组,再递归排序
     * @param arr 数组
     * @param low 数组最低位
     * @param high 数组最高位
     */
    public static void sort(int[] arr ,int low ,int high){
        if(low > high){
            return;
        }

        int midIndex = spliter(arr,low,high);
        sort(arr,low,midIndex-1);
        sort(arr,midIndex+1, high);
    }

    /**
     * 寻找数组的中间位置,把一个数组分割成一大一小两个数组
     * @param arr 数组
     * @param low 数组最低位
     * @param high 数组最高位
     * @return 中间位置
     */
    public static int spliter(int[] arr ,int low ,int high){
        int mid = arr[low];

        while (high>low){

            //最后一个数比中间值小,则把最后一个数放到一个位置
            //循环的意义在于,每次必须挪动一个位置,除非全部遍历完
            while (arr[high]>mid && high>low){
                high--;
            }
            arr[low] = arr[high];

            while (arr[low]<mid && low<high){
                low++;
            }
            arr[high] = arr[low];

        }
        //最后把mid的值赋值给该位置
        arr[high] = mid;
        return high;
    }

快速排序优化

快速排序的关键在于枢轴的选取,也就是区分两组数列的中间值,想尽办法让这个值趋于整个数列的中间。即左边的数都比这个枢轴小,右边的数都比这个数大
一般采用首,中,尾三个元素的中间那个元素作为枢纽
 

总结

排序世界观如下
 
希尔排序是直接插入排序的升级
堆排序是简单选择排序的升级
快速排序是冒泡排序的升级
 

时间复杂度列表

 

应用场景

对于数据量小的数列,排序适合选择直接插入排序
数据量大的数列,排序适合选择快速排序
如果数据量非常大,排序适合简单选择排序
原文地址:https://www.cnblogs.com/ulysses-you/p/7193780.html