算法与数据结构(2)—— 冒泡、希尔排序 及 优化

前言:

之前介绍了选择,插入以及它们的优化,发下在几乎有序的情况下,插入排序的高效性~

一、冒泡排序

  • 数组中第一个元素开始两两比较,前者比后者大就交换一下
  • 第一趟的最大值已经排上去后,那么接着从第一个元素开始比较到n-1个数,以此类推~
 public static void sort(Comparable[] arr){
        int n = arr.length;
        // n-1和n都可以,因为下面的j还会判断一次
        for(int i = 0; i < n-1; i ++){
            for(int j = i + 1; j < n; j ++){
                if(arr[i].compareTo(arr[j]) > 0)
                    swap(arr, i, j);
            }
        }
    }
1.1 优化

每一趟的Sort都将最大值放在了后面,所以之后的每一趟都可以不用再考虑了,尽管比较简单,但是时间上还有一点点的提高

 public static void sort(Comparable[] arr){
        int n = arr.length;
        for(int i = 0; i < n-1; i ++){
            for(int j = i + 1; j < n; j ++){
                if(arr[i].compareTo(arr[j]) > 0)
                    swap(arr, i, j);
            }
        }
    }

对4w个无序的数组进行测试,可知稍微有一点点的提高~


二、 希尔排序

        这是插入排序衍生的,插入排序中每个元素和之前1个元素比较,而希尔是每个元素和t个元素比较,然后t慢慢缩小成1,整个整数从无序慢慢到几乎有序,那么到最后近乎有序,t为1的话就特别快了~ 时间复杂度为O(n^(3/2))

public static void sort(Comparable[] arr){

        int n = arr.length;
        //步长为3
        int h = 1;
        while(h < n/3) h = 3 * h + 1;

        while(h >= 1){

            for(int i = h; i < n; i ++){
                // 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
                Comparable e = arr[i];
                int j = i;
                for( ; j >= h && e.compareTo(arr[j-h]) < 0; j -=h ){
                    arr[j] = arr[j-h];   //swap的优化写法
                }
                arr[j] = e;
            }
            h /= 3;
        }
    }

四、总结:

  • 希尔排序:插入的改进版,肯定是在这4种里最好的~
  • 选择排序:简单但是两重循环每次都要完成~效率慢
  • 插入排序:复杂度也是O(n^2),但是数组在几乎有序的情况下,效率甚至比 O(n* logn)的还要高,有着重要的实际意义
  • 冒泡排序:有许多的换操作,平庸~


附一张O(n^2)排序算法跑数据的图:

猜你喜欢

转载自blog.csdn.net/jae_wang/article/details/80547173