常见排序算法

1 冒泡排序

冒泡排序的原理是相邻两个元素两两比较,如果左侧数据大于右侧数据,则两者交换位置;否则不动。

时间复杂度:最好时间复杂度: O(n);最差时间复杂度:O(n²);平均时间复杂度:O(n²)

辅助空间:O(1)

稳定性:稳定

代码如下:

 /**
     * 冒泡排序
     *
     * @param numbers
     */
    public static void bubbleSort(int[] numbers) {
        int temp = 0;
        int size = numbers.length;
        for (int i = 0; i < size - 1; i++) {

            for (int j = 0; j < size - 1 - i; j++) {

                if (numbers[j] > numbers[j + 1])  //交换两数位置
                {
                    temp = numbers[j];
                    numbers[j] = numbers[j + 1];
                    numbers[j + 1] = temp;
                }
            }
            
        }
    }

2 快速排序

快速排序的原理是先在待排序的数中选择一个数作为基准值,把一组数据分为两部分,一部分数据比基准值小,另一部分数据比基准值大的;然后再对这两部分数据按同样的方式进行排序,直到整体有序为止。(分治法思想)

时间复杂度:最好时间复杂度: O(n\log_{2}n);最差时间复杂度:O(n²);平均时间复杂度:O(n\log_{2}n)

辅助空间:O(n\log_{2}n)~O(n^{2}\log_{2}n)

稳定性:不稳定

3 选择排序

选择排序的原理是首先在一组待排序的数中选择最小的数和第一位数交换位置,然后再从剩下的数中找出最小的数和第二位数交换位置,以此类推到最后位置。

时间复杂度:最好时间复杂度:O(n²);最差时间复杂度:O(n²);平均时间复杂度:O(n²)

辅助空间:O(1)

稳定性:不稳定

 /**
     * 选择排序算法
     * 在未排序序列中找到最小元素,存放到排序序列的起始位置
     * 再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。
     * 以此类推,直到所有元素均排序完毕。
     * @param numbers
     */
    public static void selectSort(int[] numbers)
    {
        int size = numbers.length; //数组长度
        int temp = 0 ; //中间变量

        for(int i = 0 ; i < size ; i++)
        {
            int minIndex = i;   //待确定的位置
            //选择出应该在第i个位置的数
            for(int j = size -1 ; j > i ; j--)
            {
                if(numbers[j] < numbers[minIndex])//查找最小值的索引
                {
                    minIndex = j;
                }
            }
            //交换两个数
            temp = numbers[i];
            numbers[i] = numbers[minIndex];
            numbers[minIndex] = temp;
        }
    }

4 插入排序

插入排序是指每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。

时间复杂度:最好时间复杂度:O(n²);最差时间复杂度:O(n²);平均时间复杂度:O(n²)

辅助空间:O(1)

稳定性:稳定

/**
     * 插入排序
     *
     * @param numbers
     */
    public static void insertSort(int[] numbers) {
        int size = numbers.length;
        int temp = 0;
        int j = 0;
        for (int i = 0; i < size; i++) {
            temp = numbers[i];
            //假如temp比前面的值小,则将前面的值后移
            for (j = i; j > 0 && temp < numbers[j - 1]; j--) {
                numbers[j] = numbers[j - 1];
            }
            numbers[j] = temp;
        }
    }

5 希尔排序

希尔排序算法实质是分组插入排序,将一组待排序的数据按步长逐级划分多组数据,然后比较分组中的数据,直到步长为1为止.(步长的确定:第一次是n/2,然后逐次再减半,直到步长为1为止)

时间复杂度:最好时间复杂度:O(n);最差时间复杂度:O(n\log_{2}n);平均时间复杂度:O(n\log_{2}n)

辅助空间:O(1)

稳定性:不稳定

6 归并排序

归并排序算法就是将一组待排序的数据划分为若干组数据,然后将每组数据进行比较排序,然后在进行合并的过程。(分治法)

时间复杂度:最好时间复杂度:O(n\log_{2}n);最差时间复杂度:O(n\log_{2}n);平均时间复杂度:O(n\log_{2}n)

辅助空间:O(n)

稳定性:稳定

7 堆排序

堆排序是一种树形选择排序。

时间复杂度:最好时间复杂度:O(n\log_{2}n);最差时间复杂度:O(n\log_{2}n);平均时间复杂度:O(n\log_{2}n)

辅助空间:O(1)

稳定性:不稳定

8 基数排序