排序算法一:选择排序、冒泡排序、插入排序

比较三种排序方法

排序方法 时间复杂度 最佳情况 额外空间复杂度 是否稳定
选择排序(Selection Sort) O ( n 2 ) O(n^{2}) O ( n 2 ) O(n^{2}) T ( 1 ) T(1)
冒泡排序(Bubble Sort) O ( n 2 ) O(n^{2}) O ( n ) O(n) T ( 1 ) T(1)
插入排序(Insertion Sort) O ( n 2 ) O(n^{2}) O ( n ) O(n) T ( 1 ) T(1)

一、选择排序

基本方法: 每次循环都找出剩余数列元素中最小的值并与剩余数列的首位交换。
即在第一次循环时找出整个数列中最小的值并与数列中第一位交换。
第二次循环时找出从第二位到最后一位中最小的元素,并与第二位进行交换。
如此继续直至第n次循环。这样的话,时间复杂度为 O ( n 2 ) O(n^{2}) ,但排序是不稳定的,即原有值相同的两个元素的先后顺序会改变。

例如: 对列表( 3, 2, 1, 5, 4 )进行排序

排好序的左子列表 未排好序的右子列表 最小元素
( ) ( 3, 2, 1, 5, 4 ) 1
( 1 ) ( 3, 2, 5, 4 ) 2
( 1, 2 ) ( 3, 5, 4 ) 3
( 1, 2, 3 ) ( 5, 4 ) 4
( 1, 2, 3, 4 ) ( 5 ) 5
( 1, 2, 3, 4, 5 ) ( )

以下为选择排序的Java代码实现:

    public static void selectionSort(int[] arr){
        for (int i = 0; i < arr.length; i++){
            int minI = i;
            for (int j = i; j < arr.length; j++){
                if (arr[j] < arr[minI]){
                    minI = j;
                }
            }
            int temp = arr[i];
            arr[i] = arr[minI];
            arr[minI] = temp;
        }
    }

二、冒泡排序

基本方法: 依次比较相邻的两个数,将较大的数放在后面。
即在第一次循环时首先比较第1个与第2个数,如第一个数比第二个数大,则交换这两个数,否则不交换。再比较第2个与第3个数,同样地,如第2个数比第3个数大,则交换。如此继续,直到比较完最后一个数和倒数第二个数并交换后,数列中最大的数会在最后一位上。
同样地,第二趟完成后数列中倒数二大的数会在倒数第二位。
如此继续直至第n次循环。这样的话,时间复杂度为 O ( n 2 ) O(n^{2}) ,且排序是稳定的,即原有值相同的两个元素的先后顺序会保持不变。
可以对此进行优化,如果某一趟并没有发生交换,则判定数列已经排好序,提前结束。这样的话,如果数列已经排好序的话,则只需循环一次。

例如: 对列表( 3, 2, 1, 5, 4 )进行排序
第一次循环:
32, 1, 5, 4 ),3>2,所以交换3和2
( 2, 31, 5, 4 ),3>1,所以交换3和1
( 2, 1, 35, 4 ),3<5,不做交换
( 2, 1, 3, 54 ),5>4,所以交换5和4
( 2, 1, 3, 4, 5 )
第二次循环:
21, 3, 4, 5 ),2>1,所以交换2和1
( 1, 23, 4, 5 ),2<3,不做交换
( 1, 2, 34, 5 ),3<5,不做交换
( 1, 2, 3, 45 ),4<5,不做交换
( 1, 2, 3, 4, 5 )
第三次循环:
12, 3, 4, 5 ),1>2,不做交换
( 1, 23, 4, 5 ),2<3,不做交换
( 1, 2, 34, 5 ),3<5,不做交换
( 1, 2, 3, 45 ),4<5,不做交换
( 1, 2, 3, 4, 5 )
因为本次循环没有交换,提前跳出循环

以下为冒泡排序的Java代码实现:

    public static void bubbleSort(int[] arr){
        boolean isSorted = true;
        for (int i = 0; i < arr.length; i++){
            for (int j = 0; j < arr.length - i - 1; j++){
                if (arr[j] > arr[j+1]){
                    int temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                    isSorted = false;
                }
            }
            if (isSorted) {
                break;
            }
        }
    }

三、插入排序

基本方法: 将列表分为两个部分,已排序部分和未排序部分,每次循环依次将元素从未排序部分插入已排序部分使之保持有序
第一次循环,将第一个元素插入已排序部分,即列表保持不变
第二次循环,将第二个元素插入含有一个元素的已排序部分
继续如此,直至第n次循环。时间复杂度为 O ( n 2 ) O(n^{2}) ,且排序是稳定的,即原有值相同的两个元素的先后顺序会保持不变。

例如: 对列表( 3, 2, 1, 5, 4 )进行排序

排好序的左子列表 未排好序的右子列表
( ) ( 3, 2, 1, 4, 5 )
( 3 ) ( 2, 1, 4, 5 )
( 2, 3 ) ( 1, 4, 5 )
( 1, 2, 3 ) ( 4, 5 )
( 1, 2, 3, 4 ) ( 5 )
( 1, 2, 3, 4, 5 ) ( )

以下为插入排序的Java代码实现:

    public static void insertionSort(int[] arr){
        for (int i = 0; i < arr.length; i++){
            int temp = arr[i];
            int j = i - 1;
            for (; j >= 0; j--){
                if (arr[j] > temp){
                    arr[j+1] = arr[j];
                }
                else {
                    break;
                }
            }
            arr[j+1] = temp;
        }
    }

猜你喜欢

转载自blog.csdn.net/zealband/article/details/88617986