龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

Java中常用的6种排序算法详细分解(3)

时间:2014-07-26 11:11来源:网络整理 作者:网络 点击:
分享到:
其实冒泡排序跟选择排序比较相像,比较次数一样,都为 n * (n + 1) / 2 ,但是冒泡排序在挑选最小值的过程中会进行额外的交换(冒泡排序在排序中只要发

其实冒泡排序跟选择排序比较相像,比较次数一样,都为 n * (n + 1) / 2 ,但是冒泡排序在挑选最小值的过程中会进行额外的交换(冒泡排序在排序中只要发现相邻元素的顺序不对就会进行交换,与之对应的是选择排序,只会在内层循环比较结束之后根据情况决定是否进行交换),所以在我看来,选择排序属于冒泡排序的改进版。

实现代码:

复制代码 代码如下:

/** 
* Bubble Sorting, it's very similar with Insertion Sorting 
*/
BUBBLE(new Sortable() { 
    public <T extends Comparable<T>> void sort(T[] array, boolean ascend) { 
        int length = array.length; 
        int lastExchangedIdx = 0; 
        for (int i = 0; i < length; i++) { 
            // mark the flag to identity whether exchange happened to false 
            boolean isExchanged = false; 
            // last compare and exchange happened before reaching index i 
            int currOrderedIdx = lastExchangedIdx > i ? lastExchangedIdx : i; 
            for (int j = length – 1; j > currOrderedIdx; j–) { 
                int compare = array[j - 1].compareTo(array[j]); 
                if (compare != 0 && compare > 0 == ascend) { 
                    exchange(array, j – 1, j); 
                    isExchanged = true; 
                    lastExchangedIdx = j; 
                } 
            } 
            // if no exchange happen means array is already in order 
            if (isExchanged == false) { 
                break; 
            } 
        } 
    } 
})

4. 希尔排序

希尔排序的诞生是由于插入排序在处理大规模数组的时候会遇到需要移动太多元素的问题。希尔排序的思想是将一个大的数组“分而治之”,划分为若干个小的数组,以 gap 来划分,比如数组 [1, 2, 3, 4, 5, 6, 7, 8] ,如果以 gap = 2 来划分,可以分为 [1, 3, 5, 7] 和 [2, 4, 6, 8] 两个数组(对应的,如 gap = 3 ,则划分的数组为: [1, 4, 7] 、 [2, 5, 8] 、 [3, 6] )然后分别对划分出来的数组进行插入排序,待各个子数组排序完毕之后再减小 gap 值重复进行之前的步骤,直至 gap = 1 ,即对整个数组进行插入排序,此时的数组已经基本上快排好序了,所以需要移动的元素会很小很小,解决了插入排序在处理大规模数组时较多移动次数的问题。

具体实例请参照插入排序。

希尔排序是插入排序的改进版,在数据量大的时候对效率的提升帮助很大,数据量小的时候建议直接使用插入排序就好了。

实现代码:

复制代码 代码如下:

/** 
* Shell Sorting 
*/
SHELL(new Sortable() { 
    public <T extends Comparable<T>> void sort(T[] array, boolean ascend) { 
        int length = array.length; 
        int gap = 1; 
 
        // use the most next to length / 3 as the first gap 
        while (gap < length / 3) { 
            gap = gap * 3 + 1; 
        } 
 
        while (gap >= 1) { 
            for (int i = gap; i < length; i++) { 
                T next = array[i]; 
                int j = i; 
                while (j >= gap) { 
                    int compare = array[j - gap].compareTo(next); 
                    // already find its position 
                    if (compare == 0 || compare < 0 == ascend) { 
                        break; 
                    } 
 
                    array[j] = array[j - gap]; 
                    j -= gap; 
                } 
                if (j != i) { 
                    array[j] = next; 
                } 
            } 
            gap /= 3; 
        } 
 
    } 
})

5. 归并排序

精彩图集

赞助商链接