常用排序算法使用

来源:互联网 发布:股票基本面分析知乎 编辑:程序博客网 时间:2024/06/01 07:15

常用排序算法有:

1、选择排序(直接选择排序、堆排序)

2、交换排序(冒泡排序、快速排序)

3、插入排序(直接插入排序、二分插入排序、Shell排序)

4、归并排序

5、桶式排序

6、基数排序

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1、直接选择排序

(1)、首先将第一个与第二个进行比较,如果第二个比第一个小,交换二者的位置,然后第二个与第三个进行比较…………第一趟找出最小的数据放在第一位置

(2)、第二趟从第二个开始,找出第二小的数据放在第二的位置

………………

经过N-1次排序之后就实现从小到大的排序,核心代码就是一个双重循环

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        Sort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void Sort(int[] arrays) {        int temp;        for (int i = 0; i < arrays.length - 1; i++) {            for (int j = i + 1; j < arrays.length; j++) {                if (arrays[i] > arrays[j]) {                    temp = arrays[i];                    arrays[i] = arrays[j];                    arrays[j] = temp;                }            }        }    }}run:排序前:[67, 62, 79, 29, 1, 46, 66, 50, 34, 93]排序后:[1, 29, 34, 46, 50, 62, 66, 67, 79, 93]成功构建 (总时间: 0 秒)


在排序中发现一个问题,由于每一次外部循环,只需要寻找最小的那个数据,然后放到开始位置去,

然后程序只要已发现前面数据比后面大,马上就会交换它们的未知,这里就增加了其开销

下面改进一下,在内部循环的时候,寻找当次外循环的最小值的位置,把这个位置记录下来,与它进行比较,然后再来交换

 private static void Sort(int[] arrays) {        int temp;        int index;        for (int i = 0; i < arrays.length - 1; i++) {            index = i;            for (int j = i + 1; j < arrays.length; j++) {                if (arrays[index] > arrays[j]) {                    index = j;                }            }            if (index != i) {                temp = arrays[i];                arrays[i] = arrays[index];                arrays[index] = temp;            }        }    }

对于直接选择排序假设有N项数据,数据交换次数最多有N-1次,程序比较次数较多,时间效率为O(N*N);但是其空间利用率高,只需要一个额外变量用于交换,空间效率O(1);直接选择排序是不稳定的。

2、堆排序

针对N个数据为:K0,K1,K2………………Kn,如果满足以下关系

Ki<=k2i+1 并且Ki<=K2i+2  (i=0,1,2…………)

则称其为小顶堆(小根堆)

反之:

Ki>=k2i+1 并且Ki>=K2i+2  (i=0,1,2…………)

则称其为大顶堆(大根堆)

步骤:

1、第一趟将索引0——N-1的数据建立大顶堆(小顶堆),就可以选出最大(最小)的数据放到根节点(索引0位置),然后将未知0与N-1位置的数据兑换,

那么最大(最小)的数据就跑到最后去了

2、第二趟将索引0——N-2的数据建立大顶堆(小顶堆),就可以选出最大(最小)的数据放到根节点(索引0位置),然后将未知0与N-2位置的数据兑换,

那么最大(最小)的数据就跑到倒数第二的位置去了

……………………以此类推就实现排序了

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        heapSort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    public static void heapSort(int[] arrays) {        for (int i = 0; i < arrays.length - 1; i++) {            buildMaxHeap(arrays, arrays.length - 1 - i);            swap(arrays, 0, arrays.length - 1 - i);        }    }    private static void buildMaxHeap(int[] arrays, int lastIndex) {        for (int i = (lastIndex - 1) / 2; i >= 0; i--) {            int k = i;            while (2 * k + 1 <= lastIndex) {//当前k节点存在子节点                int biggerIndex = 2 * k + 1;//左节点                if (biggerIndex < lastIndex) {//左节点索引小于最大索引未知、说明存在右节点且右节点索引等于lastIndex                    if (arrays[biggerIndex] < arrays[biggerIndex + 1]) {                        biggerIndex++;                    }                }                if (arrays[k] < arrays[biggerIndex]) {                    swap(arrays, k, biggerIndex);                    k = biggerIndex;                } else {                    break;                }            }//end while        }//end for    }    private static void swap(int[] arrays, int i, int j) {        int temp;        temp = arrays[i];        arrays[i] = arrays[j];        arrays[j] = temp;    }}run:排序前:[77, 69, 10, 97, 61, 56, 35, 44, 89, 81]排序后:[10, 35, 44, 56, 61, 69, 77, 81, 89, 97]成功构建 (总时间: 0 秒)

假设有N项数据,那么就要进行N-1次建堆,每次建堆耗时log2n,起时间效率为O(nlog2n);但是其空间效率很高,为O(1);堆排序是不稳定的

3、冒泡排序

冒泡排序时候,数据要不断的进行交换,属于交换排序

第一趟:比较0与1、1月2…………n-2与n-1,只要第一个数对第二个数大,就交换位置,那么最后一个就是最大的

第二趟:比较0与1、1月2…………n-3与n-2,只要第一个数对第二个数大,就交换位置,那么最后一个就是倒数第二大的

………………以此类推

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        bubbleSort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void bubbleSort(int[] arrays) {        for (int i = 0; i < arrays.length - 1; i++) {            boolean flag = false;            for (int j = 0; j < arrays.length - 1 - i; j++) {                if (arrays[j] > arrays[j + 1]) {                    swap(arrays, j, j + 1);                    flag = true;                }//end if            }//end for inner            if (!flag) {//某一趟没有发生交换说明已经排好序了                break;            }        }//end for outer    }    private static void swap(int[] arrays, int i, int j) {        int temp;        temp = arrays[i];        arrays[i] = arrays[j];        arrays[j] = temp;    }}run:排序前:[66, 8, 74, 61, 6, 99, 60, 73, 64, 53]排序后:[6, 8, 53, 60, 61, 64, 66, 73, 74, 99]成功构建 (总时间: 0 秒)

冒泡排序最坏情况下:需要做n*(n-1)/2比较;移动次数n*(n-1)*3/2;空间利用率O(1);

冒泡排序是稳定的

4、快速排序

快速排序是一种速度非常快的交换排序方法。

思路:从待排序数据中任取一个数据(第一个)做为分界值,所有比它小的放到左边,大的放到右边;

这样第一趟就形成了两个自序列,然后分别对这两个自序列递归进行,直到每一个子序列只有一个元素就可以了


package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        quickSort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void quickSort(int[] arrays) {        subSort(arrays, 0, arrays.length - 1);    }    private static void subSort(int[] arrays, int start, int end) {        if (start < end) {            int base = arrays[start];//首元素做为分界值            int left = start + 1;            int right = end;            while (1 == 1) {                while (left < end && arrays[left] <= base) {//从左到右找到大于base的                    left++;                }                while (right > start && arrays[right] >= base) {//从右到左找到小于base的                    right--;                }                if (left < right) {                    swap(arrays, left, right);                } else {                    break;                }            }//end while            swap(arrays, start, right);            subSort(arrays, start, right - 1);//递归左边            subSort(arrays, right + 1, end);//递归右边        }//end if    }    private static void swap(int[] arrays, int i, int j) {        int temp;        temp = arrays[i];        arrays[i] = arrays[j];        arrays[j] = temp;    }}run:排序前:[80, 87, 32, 30, 75, 35, 60, 17, 74, 59]排序后:[17, 30, 32, 35, 59, 60, 74, 75, 80, 87]成功构建 (总时间: 0 秒)


快速排序是不稳定的,空间利用率O(log2n) ,时间效率很高

5、直接插入排序

思路:依次将需要排序的数据按其关键字的大小插入前面的有序序列

对于一个有N个元素的序列;

1、第一趟,将第二个元素插入前面序列,目前前面那个序列只有一个元素

2、第二趟,将第三个元素插入前面序列,前面有两个数据,

…………N-1次之后就实现了排序

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        insertSort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void insertSort(int[] arrays) {        for (int i = 1; i < arrays.length; i++) {            int temp = arrays[i];            if (arrays[i] < arrays[i - 1]) {                int j = i - 1;                //先整体后移一步然后再插入                for (; j >= 0 && arrays[j] > temp; j--) {                    arrays[j + 1] = arrays[j];                }//end for inner                arrays[j + 1] = temp;            }        }//end for outer    }    private static void swap(int[] arrays, int i, int j) {        int temp;        temp = arrays[i];        arrays[i] = arrays[j];        arrays[j] = temp;    }}run:排序前:[71, 60, 29, 5, 57, 88, 89, 62, 37, 96]排序后:[5, 29, 37, 57, 60, 62, 71, 88, 89, 96]成功构建 (总时间: 0 秒)

直接插入时间效率并不高,为O(n*n),但是控件利用率高,为O(1),直接插入排序是稳定的。

6、二分插入排序

1、计算0—i-1索引的中间点,用i处的元素与(0+i-1)/2出的元素进行比较,如果i出的元素大,则在(0+i-1)/2—i-1范围内搜索;反之在0—(0+i-1)/2范围内搜索

2、按照步骤1不断的进行此操作,范围缩小到1/2,1/4,1/8,从而决定出第i个元素的插入位置

3、一旦确认出i个元素的插入位置,下面只需要将元素整体后移一步,然后将i个元素放进去

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        binaryInsertSort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void binaryInsertSort(int[] arrays) {        for (int i = 1; i < arrays.length; i++) {            int temp = arrays[i];            int left = 0;            int right = i - 1;            while (left <= right) {                int middle = (left + right) / 2;                if (temp > arrays[middle]) {                    left = middle + 1;                } else {                    right = middle - 1;                }            }//end while            for (int j = i; j > left; j--) {                arrays[j] = arrays[j - 1];            }//end for inner            arrays[left] = temp;        }//end for    }    private static void swap(int[] arrays, int i, int j) {        int temp;        temp = arrays[i];        arrays[i] = arrays[j];        arrays[j] = temp;    }}run:排序前:[81, 63, 51, 73, 55, 46, 23, 12, 18, 73]排序后:[12, 18, 23, 46, 51, 55, 63, 73, 73, 81]成功构建 (总时间: 0 秒)

二分插入排序与直接插入排序效果差不多,只是速度更快


7、Shell排序

Shell排序对直接插入排序进行了改进:通过加大排序中元素之间的间隔,并在这些有间隔的元素之间插入排序,从而使数据项大跨度移动。当这些数据经过一次排序之后,Shell排序算法减小数据项的间隔在排序,依次进行下去,这些间隔被成为增量。

h=h*3+1

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        shellSort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void shellSort(int[] arrays) {        int arrayLength = arrays.length;        int h = 1;        while (h < arrayLength / 3) {            h = h * 3 + 1;        }        while (h > 0) {            for (int i = h; i < arrayLength; i++) {                int temp = arrays[i];                if (arrays[i] < arrays[i - h]) {                    int j = i - h;                    //整体后移一位                    for (; j >= 0 && arrays[j] > temp; j -= h) {                        arrays[j + h] = arrays[j];                    }//end for inner                    arrays[j + h] = temp;                }            }//end for outer            h = (h - 1) / 3;        }//end while    }    private static void swap(int[] arrays, int i, int j) {        int temp;        temp = arrays[i];        arrays[i] = arrays[j];        arrays[j] = temp;    }}run:排序前:[36, 82, 11, 7, 5, 26, 48, 37, 11, 62]排序后:[5, 7, 11, 11, 26, 36, 37, 48, 62, 82]成功构建 (总时间: 0 秒)

Shell排序是直接插入排序的改进型,因此是稳定的,速度更快

8、归并排序
 归并排序是将两个有序的序列合并在一起组成一个新的序列。

首先将排序序列堪称N个长度为1的序列,首先做两个两个的合并,得到N/2个长度为2的有序序列,如此循环………………最终得到一个长度为N的序列。

 

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        mergeSort(arrays);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void mergeSort(int[] arrays) {        sort(arrays, 0, arrays.length - 1);    }    private static void sort(int[] arrays, int left, int right) {        if (left < right) {            //求中间位置            int center = (left + right) / 2;            //对左边数组排序            sort(arrays, left, center);            //对右边数组排序            sort(arrays, center + 1, right);            //合并            merge(arrays, left, center, right);        }    }    private static void merge(int[] arrays, int left, int center, int right) {        int[] tempArray = new int[arrays.length];        int middle = center + 1;        int tmpIndex = left;        int cpIndex = left;        while (left <= center && middle <= right) {            //选出两个数组中最小的那个放到中间数组            if (arrays[middle] >= arrays[left]) {                tempArray[tmpIndex++] = arrays[left++];            } else {                tempArray[tmpIndex++] = arrays[middle++];            }        }//end while         //剩余数据依次放入中间数组        while (middle <= right) {            tempArray[tmpIndex++] = arrays[middle++];        }        while (left <= center) {            tempArray[tmpIndex++] = arrays[left++];        }        //将中间数组的数据复制到原数组                    while (cpIndex <= right) {            arrays[cpIndex] = tempArray[cpIndex++];        }    }}run:排序前:[41, 98, 45, 20, 90, 56, 64, 80, 27, 13]排序后:[13, 20, 27, 41, 45, 56, 64, 80, 90, 98]成功构建 (总时间: 0 秒)

归并排序的空间效率很差,因为需要一个中间数组,时间复杂度为O(nlog2n);归并排序是稳定的。

9、桶式排序

桶式排序不再是基于比较的排序,其需要满足以下几个条件:

(1)、待排数据的所有值处于一个可以枚举的范围之内

(2)、这个枚举范围不应该很大,否则开销很大


package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        bucketSort(arrays, 1, 100);        System.out.println("排序后:" + Arrays.toString(arrays));    }    private static void bucketSort(int[] arrays, int min, int max) {        int[] tempArray = new int[arrays.length];        int[] buckets = new int[max - min];        //计算每个元素在序列中出现的次数        for (int i = 0; i < arrays.length; i++) {            buckets[arrays[i] - min]++;        }        //计算桶内各元素在有序序列中的位置        for (int i = 1; i < max - min; i++) {            buckets[i] = buckets[i] + buckets[i - 1];        }        //将待排数据全部复制到中间数组里面        System.arraycopy(arrays, 0, tempArray, 0, arrays.length);        //根据buckets数组的信息将待排列的数据放入对应的位置        for (int k = arrays.length - 1; k >= 0; k--) {            arrays[--buckets[tempArray[k] - min]] = tempArray[k];        }    }   }run:排序前:[83, 40, 66, 68, 34, 31, 20, 51, 13, 75]排序后:[13, 20, 31, 34, 40, 51, 66, 68, 75, 83]成功构建 (总时间: 0 秒)

桶式排序的时间效率很高,但是空间开销太大,因为需要两个中间数组;桶式排序是稳定的。
 

10、基数排序不是单一的排序算法,需要依赖其他排序算法,而这个排序算法必须是稳定的。基数排序将待排列数据分成多个关键字排序,基数排序的实质是关键字排序。

package example;import java.util.Arrays;import java.util.Random;public class Test {    public static void main(String[] args) {        Random rd = new Random();        int[] arrays = new int[10];        for (int i = 0; i < arrays.length; i++) {            arrays[i] = rd.nextInt(100);        }        System.out.println("排序前:" + Arrays.toString(arrays));        radixSort(arrays, 10, 2);        System.out.println("排序后:" + Arrays.toString(arrays));    }    /**     * 基数排序ASC(中间使用桶式排序)     *     * @param arrays 待排数组ASC     * @param radix 关键字拆分的进制 10代表十进制     * @param count 将关键字拆分成几个关键字     */    private static void radixSort(int[] arrays, int radix, int count) {        int[] tempArray = new int[arrays.length];        int[] buckets = new int[radix];        for (int i = 0, rate = 1; i < count; i++) {            Arrays.fill(buckets, 0);//重置数组,开始统计下一个关键字            System.arraycopy(arrays, 0, tempArray, 0, arrays.length);//将待排数据复制到中间数组            for (int j = 0; j < arrays.length; j++) {                int key = (tempArray[j] / rate) % radix;                buckets[key]++;            }            for (int j = 1; j < radix; j++) {                buckets[j] = buckets[j] + buckets[j - 1];            }            //按子关键字对数据进行排序            for (int k = arrays.length - 1; k >= 0; k--) {                int key = (tempArray[k] / rate) % radix;                arrays[--buckets[key]] = tempArray[k];            }            rate *= radix;        }//end for outer    }}run:排序前:[98, 39, 38, 2, 84, 39, 87, 88, 35, 79]排序后:[2, 35, 38, 39, 39, 79, 84, 87, 88, 98]成功构建 (总时间: 0 秒)

 

排序法平均时间最差情形稳定度额外空间备注冒泡O(n2)    O(n2)稳定O(1)n小时较好交换    O(n2)    O(n2)不稳定O(1)n小时较好选择O(n2)O(n2)不稳定O(1)n小时较好插入O(n2)O(n2)稳定O(1)大部分已排序时较好基数O(logRB)O(logRB)稳定O(n)

B是真数(0-9),

R是基数(个十百)

ShellO(nlogn)O(ns) 1<s<2不稳定O(1)s是所选分组快速O(nlogn)O(n2)不稳定O(nlogn)n大时较好归并O(nlogn)O(nlogn)稳定O(1)n大时较好O(nlogn)O(nlogn)不稳定O(1)n大时较好

 

package sortUtility;import java.util.Arrays;/** * * @author Administrator */public class SortUtility {//////////////////////////////////选择排序-beign/////////////////////////////////////////////    /**     * @deprecated 直接选择排序ASC     * @param arrays 需要排序的数组     */    public void directSelectSort(int[] arrays) {        for (int i = 0; i < arrays.length - 1; i++) {            for (int j = i + 1; j < arrays.length; j++) {                if (arrays[i] > arrays[j]) {                    swap(arrays, i, j);                }//end if            }//end for inner        }//end for outer    }    /**     * @deprecated 优化的直接选择排序ASC(减少数据交换次数)     * @param arrays 需要排序的数组     */    public void directSelectSortNew(int[] arrays) {        int index;        for (int i = 0; i < arrays.length - 1; i++) {            index = i;            for (int j = i + 1; j < arrays.length; j++) {                if (arrays[index] > arrays[j]) {                    index = j;                }            }            if (index != i) {                swap(arrays, i, index);            }        }    }    public void heapSort(int[] arrays) {        for (int i = 0; i < arrays.length - 1; i++) {            buildMaxHeap(arrays, arrays.length - 1 - i);            swap(arrays, 0, arrays.length - 1 - i);        }    }    /**     * @deprecated 建立大顶堆(根节点>=左子节点 AND 根节点>=右子节点)     * @param arrays 需排序数组     * @param lastIndex 最后一个节点     */    private void buildMaxHeap(int[] arrays, int lastIndex) {        for (int i = (lastIndex - 1) / 2; i >= 0; i--) {            int k = i;            while (2 * k + 1 <= lastIndex) {//当前k节点存在子节点                int biggerIndex = 2 * k + 1;//左节点                if (biggerIndex < lastIndex) {//左节点索引小于最大索引未知、说明存在右节点且右节点索引等于最大索引                    if (arrays[biggerIndex] < arrays[biggerIndex + 1]) {                        biggerIndex++;                    }                }                if (arrays[k] < arrays[biggerIndex]) {                    swap(arrays, k, biggerIndex);                    k = biggerIndex;                } else {                    break;                }            }//end while        }//end for    }//////////////////////////////////选择排序-end///////////////////////////////////////////////////////////////////////////////交换排序-begin/////////////////////////////////////////////    /**     * @deprecated 冒泡排序ASC     * @param arrays 需排序数组     */    public void bubbleSort(int[] arrays) {        for (int i = 0; i < arrays.length - 1; i++) {            boolean flag = false;            for (int j = 0; j < arrays.length - 1 - i; j++) {                if (arrays[j] > arrays[j + 1]) {                    swap(arrays, j, j + 1);                    flag = true;                }//end if            }//end for inner            if (!flag) {//某一趟没有发生交换说明已经排好序了                break;            }        }//end for outer    }    /**     * @deprecated 快速排序ASC     * @param arrays 需排序数组     */    public void quickSort(int[] arrays) {        subSort(arrays, 0, arrays.length - 1);    }    private void subSort(int[] arrays, int start, int end) {        if (start < end) {            int base = arrays[start];//首元素做为分界值            int left = start + 1;            int right = end;            while (1 == 1) {                while (left < end && arrays[left] <= base) {//从左到右找到大于base的                    left++;                }                while (right > start && arrays[right] >= base) {//从右到左找到小于base的                    right--;                }                if (left < right) {                    swap(arrays, left, right);                } else {                    break;                }            }//end while            swap(arrays, start, right);            subSort(arrays, start, right - 1);//递归左边            subSort(arrays, right + 1, end);//递归右边        }//end if    }//////////////////////////////////交换排序-end///////////////////////////////////////////////////////////////////////////////插入排序-begin/////////////////////////////////////////////    /**     * @deprecated 直接插入排序ASC     * @param arrays 需排序数组     */    public void insertSort(int[] arrays) {        for (int i = 1; i < arrays.length; i++) {            int temp = arrays[i];            if (arrays[i] < arrays[i - 1]) {                int j = i - 1;                //先整体后移一步然后再插入                for (; j >= 0 && arrays[j] > temp; j--) {                    arrays[j + 1] = arrays[j];                }//end for inner                arrays[j + 1] = temp;            }        }//end for outer    }    /**     * @deprecated 二分插入排序ASC     * @param arrays 需排序数组     */    public void binaryInsertSort(int[] arrays) {        for (int i = 1; i < arrays.length; i++) {            int temp = arrays[i];            int left = 0;            int right = i - 1;            while (left <= right) {                int middle = (left + right) / 2;                if (temp > arrays[middle]) {                    left = middle + 1;                } else {                    right = middle - 1;                }            }//end while            for (int j = i; j > left; j--) {                arrays[j] = arrays[j - 1];            }//end for inner            arrays[left] = temp;        }//end for    }    /**     * @deprecated Shell排序ASC     * @param arrays 需排序数组     */    public void shellSort(int[] arrays) {        int arrayLength = arrays.length;        int h = 1;        while (h < arrayLength / 3) {            h = h * 3 + 1;        }        while (h > 0) {            for (int i = h; i < arrayLength; i++) {                int temp = arrays[i];                if (arrays[i] < arrays[i - h]) {                    int j = i - h;                    //整体后移一位                    for (; j >= 0 && arrays[j] > temp; j -= h) {                        arrays[j + h] = arrays[j];                    }//end for inner                    arrays[j + h] = temp;                }            }//end for outer            h = (h - 1) / 3;        }//end while    }//////////////////////////////////插入排序-end/////////////////////////////////////////////    //////////////////////////////////归并排序-begin///////////////////////////////////////////    /**     * @deprecated 归并排序ASC     * @param arrays 待排数组     */    public void mergeSort(int[] arrays) {        sort(arrays, 0, arrays.length - 1);    }    /**     * @deprecated 递归排序     * @param arrays 待排数组     * @param left 数组第一个元素索引     * @param right 数组最后一个元素索引     */    private void sort(int[] arrays, int left, int right) {        if (left < right) {            //求中间位置            int center = (left + right) / 2;            //对左边数组排序            sort(arrays, left, center);            //对右边数组排序            sort(arrays, center + 1, right);            //合并            merge(arrays, left, center, right);        }    }    /**     * @deprecated 将两个数组归并     * @param arrays 待排数组     * @param left 左数组第一个元素索引     * @param center 左数组最后一个元素 center+1为右数组第一个元素索引     * @param right 右数组最后一个元素索引     */    private void merge(int[] arrays, int left, int center, int right) {        int[] tempArray = new int[arrays.length];        int middle = center + 1;        int tmpIndex = left;        int cpIndex = left;        while (left <= center && middle <= right) {            //选出两个数组中最小的那个放到中间数组            if (arrays[middle] >= arrays[left]) {                tempArray[tmpIndex++] = arrays[left++];            } else {                tempArray[tmpIndex++] = arrays[middle++];            }        }//end while         //剩余数据依次放入中间数组        while (middle <= right) {            tempArray[tmpIndex++] = arrays[middle++];        }        while (left <= center) {            tempArray[tmpIndex++] = arrays[left++];        }        //将中间数组的数据复制到原数组                    while (cpIndex <= right) {            arrays[cpIndex] = tempArray[cpIndex++];        }    }//////////////////////////////////归并排序-end/////////////////////////////////////////////    //////////////////////////////////桶式排序-begin///////////////////////////////////////////    /**     * @deprecated 桶式排序ASC     * @param min 枚举范围最小值     * @param max 枚举范围最大值     */    public void bucketSort(int[] arrays, int min, int max) {        int[] tempArray = new int[arrays.length];        int[] buckets = new int[max - min];        //计算每个元素在序列中出现的次数        for (int i = 0; i < arrays.length; i++) {            buckets[arrays[i] - min]++;        }        //计算桶内各元素在有序序列中的位置        for (int i = 1; i < max - min; i++) {            buckets[i] = buckets[i] + buckets[i - 1];        }        //将待排数据全部复制到中间数组里面        System.arraycopy(arrays, 0, tempArray, 0, arrays.length);        //根据buckets数组的信息将待排列的数据放入对应的位置        for (int k = arrays.length - 1; k >= 0; k--) {            arrays[--buckets[tempArray[k] - min]] = tempArray[k];        }    }//////////////////////////////////桶式排序-end/////////////////////////////////////////////    //////////////////////////////////基数排序-begin///////////////////////////////////////////    /**     * 基数排序ASC(中间使用桶式排序)     *     * @param arrays 待排数组ASC     * @param radix 关键字拆分的进制 10代表十进制     * @param count 将关键字拆分成几个关键字     */    public void radixSort(int[] arrays, int radix, int count) {        int[] tempArray = new int[arrays.length];        int[] buckets = new int[radix];        for (int i = 0, rate = 1; i < count; i++) {            Arrays.fill(buckets, 0);//重置数组,开始统计下一个关键字            System.arraycopy(arrays, 0, tempArray, 0, arrays.length);//将待排数据复制到中间数组            for (int j = 0; j < arrays.length; j++) {                int key = (tempArray[j] / rate) % radix;                buckets[key]++;            }            for (int j = 1; j < radix; j++) {                buckets[j] = buckets[j] + buckets[j - 1];            }            //按子关键字对数据进行排序            for (int k = arrays.length - 1; k >= 0; k--) {                int key = (tempArray[k] / rate) % radix;                arrays[--buckets[key]] = tempArray[k];            }            rate *= radix;        }//end for outer    }//////////////////////////////////基数排序-end/////////////////////////////////////////////       /**     * @deprecated 交换数据     */    private void swap(int[] arrays, int i, int j) {        int temp;        temp = arrays[i];        arrays[i] = arrays[j];        arrays[j] = temp;    }}


 

 

原创粉丝点击