提供了以下排序:冒泡排序

选择排序

插入排序

希尔排序

快速排序

归并排序

桶排序

堆排序

package com.xingej.algorithm.sort;import java.util.ArrayList;import java.util.Collections;/** * 排序工具类 *  * @author erjun 2017年12月13日 上午8:38:22 */public class SortUtils {    // 私有构造器,禁止外界创建对象    private SortUtils() {    }    // --------1、冒泡排序------    /**     *      * 冒泡排序核心:1、从数组的最后一个元素,开始比较;2、两两比较,满足条件的话,就需要进行位置的互换     *      * 实际生活中:小学时,需要根据身高进行座位排序,就可以使用冒泡排序进行。     *      */    public static void bubbleSort(int[] arr) {        int temp;        // 4 3 2 1,按冒泡排序的话,需要进行3轮比较可以了        for (int i = 0; i  i; j--) {                // 后面的/下面的水泡 小于 上面的水泡,就移位                if (arr[j] b,那么minIndex就是b的下标        int value;        for (int i = 0; i  arr[j]) {                    minIndex = j;// 将最小下标赋值给minIndex                }            }            // 将最小值与第一个元素,进行交换            arr[i] = arr[minIndex];            arr[minIndex] = value;        }    }    // --------3、插入排序------    /**     * 插入排序,的思想跟冒泡排序和选择排序不同     *      * 使用场景很像打牌时,每抓到一个张牌,按照大小插入到"已经排序好"的牌里     *      * 实际应用场景:有排序好的元素,还有一些未排序的元素,这个时候可以考虑插入排序     *      * 其实,将待排序的元素,插入到已经排序好的元素时,     *      * 可以使用别的排序方法,来进行,不必循序查询比较排序,可以使用快速排序     *      * @param arr     */    public static void insertSort(int[] arr) {        // right表示,未排序的元素        for (int right = 1; right = 0 && arr[left] > temp) {                arr[left + 1] = arr[left];                left--;            }            // 为什么left+1呢?            // 因为,上面的while循环中,left 减 1 之后, 不满足循环条件的,            // 因此,需要将temp值放到left+1的位置上去            arr[left + 1] = temp;        }    }    // --------4、希尔排序------    public static void shellSort(int[] arr) {        int left; // 左边下标,表示,已经排序好的元素        int right; // 右边下标,表示,待排序元素/就是没有排序的元素        int temp; // 临时存储        int h = 1; // 初始间隔为1;        // 计算最大间隔        while (h  0) {            // 表示循环待排序的元素            for (right = h; right h-1,                // 目前我认为是,保证arr[left-h] 得有值,不能为空,或者说,报空指针异常吧                while (left > h - 1 && arr[left - h] >= temp) {                    arr[left] = arr[left - h];                    left = left - h;                }                // 这里,千万不要写成下面的形式, 不能再left-h,因为,上面的while()循环,已经减去了                // arr[left - h] = temp;                arr[left] = temp;            }            // 重新调整排序间隔            h = (h - 1) / 3;        }    }    // --------5、快速排序------    public static void quickSort(int arr[]) {        recQuickSort(arr, 0, arr.length - 1);    }    // 使用递归和划分技术进行快速排序    private static void recQuickSort(int arr[], int left, int right) {        int size = right - left + 1;        if (size  pivot)                ;            if (leftPtr >= rightPtr) {                break; // 结束时,leftPtr = rightPtr            } else {                swap(arr, leftPtr, rightPtr); // 交换            }        }        swap(arr, leftPtr, right - 1);        return leftPtr;    }    // 找出中间值    // 索引为left,right,以及中间值的 进行排序,    private static int medianof3(int arr[], int left, int right) {        int centerIndex = (left + right) / 2;        if (arr[left] > arr[centerIndex]) {            swap(arr, left, centerIndex);        }        if (arr[left] > arr[right]) {            swap(arr, left, right);        }        if (arr[centerIndex] > arr[right]) {            swap(arr, centerIndex, right);        }        swap(arr, centerIndex, right - 1);        return arr[right - 1];    }    private static void insertSort(int arr[], int left, int right) {        int in, out;        int temp; // 临时缓存,待存储的元素        for (out = left + 1; out <= right; out++) {            temp = arr[out];            in = out;            while (in > left && arr[in - 1] >= temp) {                arr[in] = arr[in - 1];                in--;            }            arr[in] = temp;        }    }    private static void swap(int arr[], int left, int right) {        int temp = arr[left];        arr[left] = arr[right];        arr[right] = temp;    }    // --------6、归并排序------    // 归并两个已经有序的数组    // 首先将数组,拆分成两部分,左边做成有序的,同样,右边也做成有序的。    // 将这两个有序的数组,组合生成第3个有序的数组,    // 时间复杂度O(N*logN)    // 缺点:消耗内存;    public static void mergeSort(int arr[]) {        // 生成临时的缓存数组,用于临时排序        int[] workSpace = new int[arr.length];        recMergeSort(arr, workSpace, 0, arr.length - 1);    }    // lowerBound,upperBound 全是数组下标    private static void recMergeSort(int arr[], int workSpace[], int lowerBound, int upperBound) {        if (lowerBound == upperBound) {            return;        } else {            int mid = (lowerBound + upperBound) / 2;            // 递归前半部分            recMergeSort(arr, workSpace, lowerBound, mid);            // 递归后半部分            recMergeSort(arr, workSpace, mid + 1, upperBound);            // 进行合并            merge(arr, workSpace, lowerBound, mid + 1, upperBound);        }    }    /**     *      * @param arr     *            被排序的数组     * @param workSpace     *            临时缓存,进行排序的     * @param lowPtr     *            前半部分,最小下标     * @param highPtr     *            后半部分,最小下标     * @param upperBound     *            后半部分,最大下标     */    private static void merge(int arr[], int workSpace[], int lowPtr, int highPtr, int upperBound) {        int i = 0;        int lowerBound = lowPtr;// 前半部分的最小下标,进行缓存        int mid = highPtr - 1;        int n = upperBound - lowerBound + 1;        while (lowPtr <= mid && highPtr <= upperBound) {            if (arr[lowPtr] > bucketArr = new ArrayList<>();        for (int i = 0; i ());        }        // 遍历数组,将每个元素放入桶中        for (int i = 0; i  arrayList = bucketArr.get(i);            for (Integer key : arrayList) {                arr[j++] = key;            }        }    }    // --------8、堆排序------    // 堆特点:    // 1、它是完全的二叉树,除了树的最后一层节点不需要是满的,其他的每一层从左到右都完全是满的    // 2、它常常是用一个数组来实现堆的    // 3、堆中的每一个节点都满足的条件是,父节点的关键字要大于所有的子节点    public static void heapSort(int arr[]) {        int size = arr.length;        Heap heap = new Heap(size);        for (int i = 0; i = 0; j--) {            heap.trickleDown(j);        }        // 通过循环删除最大项,再把删除的数据,数组中的指定的位置,如从后往前方;        // 结果就是从小到大排序        for (int j = size - 1; j >= 0; j--) {            Node biggestNode = heap.remove();// 取出最大的数据项            heap.insertAt(j, biggestNode);        }        System.out.println("----打印排序后的堆----");        heap.displayArray();    }    // 堆排序,    // 堆是二叉树,因此,需要创建这个节点,来存储数据    // 堆的特点:父节点的值要大于子节点,左右子节点大小无关系,不要求左子节点小于右子节点    static class Node {        private int iData;        public Node(int key) {            iData = key;        }        public int getKey() {            return iData;        }        public void setKey(int id) {            iData = id;        }    }    // 创建堆    static class Heap {        private Node[] heapArray;        private int maxSize;        private int currentSize;        public Heap(int mx) {            maxSize = mx;            currentSize = 0;            heapArray = new Node[maxSize];        }        public boolean isEmpty() {            return currentSize == 0;        }        // 插入指定的位置        public void insertAt(int index, Node node) {            heapArray[index] = node;        }        public void incrementSize() {            currentSize++;        }        public Node remove() {            Node root = heapArray[0];            heapArray[0] = heapArray[--currentSize];// 把最后一个元素,赋值到根元素上            trickleDown(0);// 开始向下调整            return root;        }        // 向下调整        public void trickleDown(int index) {            int largerChild;            Node top = heapArray[index];            while (index = heapArray[largerChild].getKey()) {                    break;                }                heapArray[index] = heapArray[largerChild];                index = largerChild;            }            heapArray[index] = top;        }        // 树状的方式,显示堆        public void displayHeap() {            int nBlanks = 32;            int itemsPerRow = 1;// 层数判断            int column = 0;            int j = 0;            String dots = "-------------------------";            System.out.println(dots + dots);            while (currentSize > 0) {                if (column == 0) {                    for (int k = 0; k
测试用例:package com.xingej.algorithm.sort;import org.junit.Before;import org.junit.Test;public class SortTest {    private int max = 20;    private int[] arr = new int[max];    // 初始化数组    @Before    public void initArray() {        for (int i = 0; i