常用排序算法

package org.bond.sort;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

/**
 * 插入排序:直接插入排序;希尔排序
 * 交换排序:冒泡排序;快速排序
 * 选择排序:简单选择排序;堆排序
 * 归并排序
 * 基数排序
 */
public class SortingAlgorithm {

    /**
     * 归并排序
     *
     * @param data 待排序数组
     */
    public static <T> void mergeSortAsc(T[] data) {
        mergeSortAsc(data, 0, data.length - 1);
    }

    /**
     * 归并排序
     *
     * @param data  待排序数组
     * @param left  左下标
     * @param right 有下标
     */
    private static <T> void mergeSortAsc(T[] data, int left, int right) {
        if (left >= right) {
            return;
        }
        // 找出中间索引
        int center = (left + right) / 2;
        // 对左边数组进行递归
        mergeSortAsc(data, left, center);
        // 对右边数组进行递归
        mergeSortAsc(data, center + 1, right);
        // 合并
        mergeSortAsc(data, left, center, right);
    }

    /**
     * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
     *
     * @param data   数组对象
     * @param left   左数组的第一个元素的索引
     * @param center 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
     * @param right  右数组最后一个元素的索引
     */
    private static <T> void mergeSortAsc(T[] data, int left, int center, int right) {
        // 克隆临时数组
        T[] tmpArr = data.clone();

        // 右数组第一个元素索引
        int mid = center + 1;
        // third 记录临时数组的索引
        int third = left;
        // 缓存左数组第一个元素的索引
        int tmp = left;
        while (left <= center && mid <= right) {
            // 从两个数组中取出最小的放入临时数组
            if (compare(data[left], data[mid]) < 1) {
                tmpArr[third++] = data[left++];
            } else {
                tmpArr[third++] = data[mid++];
            }
        }
        // 剩余部分依次放入临时数组
        while (mid <= right) {
            tmpArr[third++] = data[mid++];
        }
        while (left <= center) {
            tmpArr[third++] = data[left++];
        }
        // 将临时数组中的内容拷贝回原数组中
        // (原left-right范围的内容被复制回原数组)
        while (tmp <= right) {
            data[tmp] = tmpArr[tmp++];
        }
    }

    /**
     * 归并排序
     *
     * @param data 待排序数组
     */
    public static <T> void mergeSortDesc(T[] data) {
        mergeSortDesc(data, 0, data.length - 1);
    }

    /**
     * 归并排序
     *
     * @param data  待排序数组
     * @param left  左下标
     * @param right 有下标
     */
    private static <T> void mergeSortDesc(T[] data, int left, int right) {
        if (left >= right) {
            return;
        }
        // 找出中间索引
        int center = (left + right) / 2;
        // 对左边数组进行递归
        mergeSortDesc(data, left, center);
        // 对右边数组进行递归
        mergeSortDesc(data, center + 1, right);
        // 合并
        mergeSortDesc(data, left, center, right);
    }

    /**
     * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
     *
     * @param data   数组对象
     * @param left   左数组的第一个元素的索引
     * @param center 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
     * @param right  右数组最后一个元素的索引
     */
    private static <T> void mergeSortDesc(T[] data, int left, int center, int right) {
        // 克隆临时数组
        T[] tmpArr = data.clone();

        // 右数组第一个元素索引
        int mid = center + 1;
        // third 记录临时数组的索引
        int third = left;
        // 缓存左数组第一个元素的索引
        int tmp = left;
        while (left <= center && mid <= right) {
            // 从两个数组中取出最大的放入临时数组
            if (compare(data[left], data[mid]) > -1) {
                tmpArr[third++] = data[left++];
            } else {
                tmpArr[third++] = data[mid++];
            }
        }
        // 剩余部分依次放入临时数组
        while (mid <= right) {
            tmpArr[third++] = data[mid++];
        }
        while (left <= center) {
            tmpArr[third++] = data[left++];
        }
        // 将临时数组中的内容拷贝回原数组中
        // (原left-right范围的内容被复制回原数组)
        while (tmp <= right) {
            data[tmp] = tmpArr[tmp++];
        }
    }

    /**
     * 归并排序
     *
     * @param data 待排序List
     */
    public static <T> void mergeSortAsc(List<T> data) {
        mergeSortAsc(data, 0, data.size() - 1);
    }

    /**
     * 归并排序
     *
     * @param data  待排序List
     * @param left  左下标
     * @param right 有下标
     */
    private static <T> void mergeSortAsc(List<T> data, int left, int right) {
        if (left >= right) {
            return;
        }
        // 找出中间索引
        int center = (left + right) / 2;
        // 对左边List进行递归
        mergeSortAsc(data, left, center);
        // 对右边List进行递归
        mergeSortAsc(data, center + 1, right);
        // 合并
        mergeSortAsc(data, left, center, right);
    }

    /**
     * 将两个List进行归并,归并前面2个List已有序,归并后依然有序
     *
     * @param data   List对象
     * @param left   左List的第一个元素的索引
     * @param center 左List的最后一个元素的索引,center+1是右List第一个元素的索引
     * @param right  右List最后一个元素的索引
     */
    private static <T> void mergeSortAsc(List<T> data, int left, int center, int right) {
        // 克隆临时List
        List<T> tmpArr = new ArrayList<T>(data.size());
        for (int i = 0; i < data.size(); i++) {
            tmpArr.add(i, data.get(i));
        }

        // 右List第一个元素索引
        int mid = center + 1;
        // third 记录临时List的索引
        int third = left;
        // 缓存左List第一个元素的索引
        int tmp = left;
        while (left <= center && mid <= right) {
            // 从两个List中取出最小的放入临时List
            if (compare(data.get(left), data.get(mid)) < 1) {
                tmpArr.set(third++, data.get(left++));
            } else {
                tmpArr.set(third++, data.get(mid++));
            }
        }
        // 剩余部分依次放入临时List
        while (mid <= right) {
            tmpArr.set(third++, data.get(mid++));
        }
        while (left <= center) {
            tmpArr.set(third++, data.get(left++));
        }
        // 将临时List中的内容拷贝回原List中
        // (原left-right范围的内容被复制回原List)
        while (tmp <= right) {
            data.set(tmp, tmpArr.get(tmp++));
        }
    }

    /**
     * 归并排序
     *
     * @param data 待排序List
     */
    public static <T> void mergeSortDesc(List<T> data) {
        mergeSortDesc(data, 0, data.size() - 1);
    }

    /**
     * 归并排序
     *
     * @param data  待排序List
     * @param left  左下标
     * @param right 有下标
     */
    private static <T> void mergeSortDesc(List<T> data, int left, int right) {
        if (left >= right) {
            return;
        }
        // 找出中间索引
        int center = (left + right) / 2;
        // 对左边List进行递归
        mergeSortDesc(data, left, center);
        // 对右边List进行递归
        mergeSortDesc(data, center + 1, right);
        // 合并
        mergeSortDesc(data, left, center, right);
    }

    /**
     * 将两个List进行归并,归并前面2个List已有序,归并后依然有序
     *
     * @param data   List对象
     * @param left   左List的第一个元素的索引
     * @param center 左List的最后一个元素的索引,center+1是右List第一个元素的索引
     * @param right  右List最后一个元素的索引
     */
    private static <T> void mergeSortDesc(List<T> data, int left, int center, int right) {
        // 克隆临时List
        List<T> tmpArr = new ArrayList<T>(data.size());
        for (int i = 0; i < data.size(); i++) {
            tmpArr.add(i, data.get(i));
        }

        // 右List第一个元素索引
        int mid = center + 1;
        // third 记录临时List的索引
        int third = left;
        // 缓存左List第一个元素的索引
        int tmp = left;
        while (left <= center && mid <= right) {
            // 从两个List中取出最大的放入临时List
            if (compare(data.get(left), data.get(mid)) > -1) {
                tmpArr.set(third++, data.get(left++));
            } else {
                tmpArr.set(third++, data.get(mid++));
            }
        }
        // 剩余部分依次放入临时List
        while (mid <= right) {
            tmpArr.set(third++, data.get(mid++));
        }
        while (left <= center) {
            tmpArr.set(third++, data.get(left++));
        }
        // 将临时List中的内容拷贝回原List中
        // (原left-right范围的内容被复制回原List)
        while (tmp <= right) {
            data.set(tmp, tmpArr.get(tmp++));
        }
    }

    /**
     * 插入排序ASC
     *
     * @param data 待排序数据数组
     */
    public static <T> void insertSortAsc(T[] data) {
        for (int i = 1; i < data.length; i++) {
            int j = i - 1;
            T value = data[i];
            while (j >= 0 && compare(data[j], value) > 0) {
                data[j + 1] = data[j];
                j--;
            }
            data[j + 1] = value;
        }
    }

    /**
     * 插入排序Desc
     *
     * @param data 待排序数组
     */
    public static <T> void insertSortDesc(T[] data) {
        for (int i = 1; i < data.length; i++) {
            int j = i - 1;
            T value = data[i];
            while (j >= 0 && compare(data[j], value) < 0) {
                data[j + 1] = data[j];
                j--;
            }
            data[j + 1] = value;
        }
    }

    /**
     * 插入排序Asc
     *
     * @param data 待排序List
     */
    public static <T> void insertSortAsc(List<T> data) {
        for (int i = 1; i < data.size(); i++) {
            int j = i - 1;
            T value = data.get(i);
            while (j >= 0 && compare(data.get(j), value) > 0) {
                data.set(j + 1, data.get(j));
                j--;
            }
            data.set(j + 1, value);
        }
    }

    /**
     * 插入排序Desc
     *
     * @param data 待排序List
     */
    public static <T> void insertSortDesc(List<T> data) {
        for (int i = 1; i < data.size(); i++) {
            int j = i - 1;
            T value = data.get(i);
            while (j >= 0 && compare(data.get(j), value) < 0) {
                data.set(j + 1, data.get(j));
                j--;
            }
            data.set(j + 1, value);
        }
    }

    /**
     * 希尔排序Asc
     *
     * @param data 待排序数组
     */
    public static <T> void shellSortAsc(T[] data) {
        double len = data.length;
        while (true) {
            len = Math.ceil(len / 2);
            //获取增量d(n/2,n为要排序数的个数)
            int d = (int) len;
            for (int x = 0; x < d; x++) {
                for (int i = x + d; i < data.length; i += d) {
                    int j = i - d;
                    T temp = data[i];
                    for (; j >= 0 && compare(temp, data[j]) == -1; j -= d) {
                        data[j + d] = data[j];
                    }
                    data[j + d] = temp;
                }
            }
            if (d == 1) {
                break;
            }
        }
    }

    /**
     * 希尔排序Desc
     *
     * @param data 待排序数组
     */
    public static <T> void shellSortDesc(T[] data) {
        double len = data.length;
        while (true) {
            len = Math.ceil(len / 2);
            //获取增量d(n/2,n为要排序数的个数)
            int d = (int) len;
            for (int x = 0; x < d; x++) {
                for (int i = x + d; i < data.length; i += d) {
                    int j = i - d;
                    T temp = data[i];
                    for (; j >= 0 && compare(temp, data[j]) == 1; j -= d) {
                        data[j + d] = data[j];
                    }
                    data[j + d] = temp;
                }
            }
            if (d == 1) {
                break;
            }
        }
    }

    /**
     * 希尔排序Asc
     *
     * @param data 待排序List
     */
    public static <T> void shellSortAsc(List<T> data) {
        double len = data.size();
        while (true) {
            len = Math.ceil(len / 2);
            //获取增量d(n/2,n为要排序数的个数)
            int d = (int) len;
            for (int x = 0; x < d; x++) {
                for (int i = x + d; i < data.size(); i += d) {
                    int j = i - d;
                    T temp = data.get(i);
                    for (; j >= 0 && compare(temp, data.get(j)) == -1; j -= d) {
                        data.set(j + d, data.get(j));
                    }
                    data.set(j + d, temp);
                }
            }
            if (d == 1) {
                break;
            }
        }
    }

    /**
     * 希尔排序Desc
     *
     * @param data 待排序List
     */
    public static <T> void shellSortDesc(List<T> data) {
        double len = data.size();
        while (true) {
            len = Math.ceil(len / 2);
            //获取增量d(n/2,n为要排序数的个数)
            int d = (int) len;
            for (int x = 0; x < d; x++) {
                for (int i = x + d; i < data.size(); i += d) {
                    int j = i - d;
                    T temp = data.get(i);
                    for (; j >= 0 && compare(temp, data.get(j)) == 1; j -= d) {
                        data.set(j + d, data.get(j));
                    }
                    data.set(j + d, temp);
                }
            }
            if (d == 1) {
                break;
            }
        }
    }

    /**
     * 冒泡排序Asc
     *
     * @param data 待排序数组
     */
    public static <T> void bubbleSortAsc(T[] data) {
        for (int i = 0; i < data.length - 1; i++) {
            for (int j = i + 1; j < data.length; j++) {
                if (compare(data[i], data[j]) > 0) {
                    T temp = data[i];
                    data[i] = data[j];
                    data[j] = temp;
                }
            }
        }
    }

    /**
     * 冒泡排序Desc
     *
     * @param data 待排序数组
     */
    public static <T> void bubbleSortDesc(T[] data) {
        for (int i = 0; i < data.length - 1; i++) {
            for (int j = i + 1; j < data.length; j++) {
                if (compare(data[i], data[j]) < 0) {
                    T temp = data[i];
                    data[i] = data[j];
                    data[j] = temp;
                }
            }
        }
    }

    /**
     * 冒泡排序Asc
     *
     * @param data 待排序List
     */
    public static <T> void bubbleSortAsc(List<T> data) {
        for (int i = 0; i < data.size() - 1; i++) {
            for (int j = i + 1; j < data.size(); j++) {
                if (compare(data.get(i), data.get(j)) > 0) {
                    T temp = data.get(i);
                    data.set(i, data.get(j));
                    data.set(j, temp);
                }
            }
        }
    }

    /**
     * 冒泡排序Desc
     *
     * @param data 待排序List
     */
    public static <T> void bubbleSortDesc(List<T> data) {
        for (int i = 0; i < data.size() - 1; i++) {
            for (int j = i + 1; j < data.size(); j++) {
                if (compare(data.get(i), data.get(j)) < 0) {
                    T temp = data.get(i);
                    data.set(i, data.get(j));
                    data.set(j, temp);
                }
            }
        }
    }

    /**
     * 快速排序ASC
     *
     * @param data 待排序数据数组
     */
    public static <T> void quickSortAsc(T[] data) {
        int left = 0;
        int right = data.length - 1;

        quickSortAsc(data, left, right);
    }

    /**
     * 快速排序Desc
     *
     * @param data 待排序数据数组
     */
    public static <T> void quickSortDesc(T[] data) {
        int left = 0;
        int right = data.length - 1;

        quickSortDesc(data, left, right);
    }

    /**
     * 快速排序ASC
     *
     * @param data 待排序数据List
     */
    public static <T> void quickSortAsc(List<T> data) {
        int left = 0;
        int right = data.size() - 1;

        quickSortAsc(data, left, right);
    }

    /**
     * 快速排序Desc
     *
     * @param data 待排序数据List
     */
    public static <T> void quickSortDesc(List<T> data) {
        int left = 0;
        int right = data.size() - 1;

        quickSortDesc(data, left, right);
    }

    /**
     * 快速排序ASC
     *
     * @param data  待排序数据数组
     * @param left  左边下标
     * @param right 右边下标
     */
    private static <T> void quickSortAsc(T[] data, int left, int right) {
        if (left < right) {
            T base = data[left];//选择第一个值为基准值
            int i = left, j = right;

            do {
                //将数组分成两部分,左边小于基准值;右边大于基准值
                while (compare(data[i], base) == -1 && i < right) {
                    i++;
                }
                while (compare(data[j], base) == 1 && j > left) {
                    j--;
                }
                if (i <= j) {
                    T temp = data[i];
                    data[i] = data[j];
                    data[j] = temp;
                    i++;
                    j--;
                }
            } while (i <= j);

            if (left < j) {
                quickSortAsc(data, left, j);
            }
            if (right > i) {
                quickSortAsc(data, i, right);
            }
        }
    }

    /**
     * 快速排序Desc
     *
     * @param data  待排序数据数组
     * @param left  左边下标
     * @param right 右边下标
     */
    private static <T> void quickSortDesc(T[] data, int left, int right) {
        if (left < right) {
            T base = data[left];//选择第一个值为基准值
            int i = left, j = right;

            do {
                //将数组分成两部分,左边小于基准值;右边大于基准值
                while (compare(data[i], base) == 1 && i < right) {
                    i++;
                }
                while (compare(data[j], base) == -1 && j > left) {
                    j--;
                }
                if (i <= j) {
                    T temp = data[i];
                    data[i] = data[j];
                    data[j] = temp;
                    i++;
                    j--;
                }
            } while (i <= j);

            if (left < j) {
                quickSortDesc(data, left, j);
            }
            if (right > i) {
                quickSortDesc(data, i, right);
            }
        }
    }

    /**
     * 快速排序ASC
     *
     * @param data  待排序数据List
     * @param left  左边下标
     * @param right 右边下标
     */
    private static <T> void quickSortAsc(List<T> data, int left, int right) {
        if (left < right) {
            T base = data.get(left);//选择第一个值为基准值
            int i = left, j = right;

            do {
                //将数组分成两部分,左边小于基准值;右边大于基准值
                while (compare(data.get(i), base) == -1 && i < right) {
                    i++;
                }
                while (compare(data.get(j), base) == 1 && j > left) {
                    j--;
                }
                if (i <= j) {
                    T temp = data.get(i);
                    data.set(i, data.get(j));
                    data.set(j, temp);
                    i++;
                    j--;
                }
            } while (i <= j);

            if (left < j) {
                quickSortAsc(data, left, j);
            }
            if (right > i) {
                quickSortAsc(data, i, right);
            }
        }
    }

    /**
     * 快速排序Desc
     *
     * @param data  待排序数据List
     * @param left  左边下标
     * @param right 右边下标
     */
    private static <T> void quickSortDesc(List<T> data, int left, int right) {
        if (left < right) {
            T base = data.get(left);//选择第一个值为基准值
            int i = left, j = right;

            do {
                //将数组分成两部分,左边小于基准值;右边大于基准值
                while (compare(data.get(i), base) == 1 && i < right) {
                    i++;
                }
                while (compare(data.get(j), base) == -1 && j > left) {
                    j--;
                }
                if (i <= j) {
                    T temp = data.get(i);
                    data.set(i, data.get(j));
                    data.set(j, temp);
                    i++;
                    j--;
                }
            } while (i <= j);

            if (left < j) {
                quickSortDesc(data, left, j);
            }
            if (right > i) {
                quickSortDesc(data, i, right);
            }
        }
    }

    /**
     * 选择排序Asc
     *
     * @param data 待排序数组
     */
    public static <T> void selectSortAsc(T[] data) {
        for (int i = 0; i < data.length; i++) {
            int minIndex = getMinIndex(data, i, data.length - 1);
            if (minIndex != i) {
                T temp = data[i];
                data[i] = data[minIndex];
                data[minIndex] = temp;
            }
        }
    }

    /**
     * 选择排序Asc
     *
     * @param data 待排序List
     */
    public static <T> void selectSortAsc(List<T> data) {
        for (int i = 0; i < data.size(); i++) {
            int minIndex = getMinIndex(data, i, data.size() - 1);
            if (minIndex != i) {
                T temp = data.get(i);
                data.set(i, data.get(minIndex));
                data.set(minIndex, temp);
            }
        }
    }

    /**
     * 选择排序Desc
     *
     * @param data 待排序数组
     */
    public static <T> void selectSortDesc(T[] data) {
        for (int i = 0; i < data.length; i++) {
            int minIndex = getMaxIndex(data, i, data.length - 1);
            if (minIndex != i) {
                T temp = data[i];
                data[i] = data[minIndex];
                data[minIndex] = temp;
            }
        }
    }

    /**
     * 选择排序Desc
     *
     * @param data 待排序List
     */
    public static <T> void selectSortDesc(List<T> data) {
        for (int i = 0; i < data.size(); i++) {
            int minIndex = getMaxIndex(data, i, data.size() - 1);
            if (minIndex != i) {
                T temp = data.get(i);
                data.set(i, data.get(minIndex));
                data.set(minIndex, temp);
            }
        }
    }

    /**
     * 堆排序ASC
     *
     * @param data 待排序数组
     */
    public static <T> void heapSortAsc(T[] data) {
        heapSortAsc(data, data.length - 1);
    }

    /**
     * 堆排序ASC
     *
     * @param data
     * @param index
     */
    private static <T> void heapSortAsc(T[] data, int index) {
        if (index > 0) {
            initHeapAsc(data, index);

            T temp = data[0];
            data[0] = data[index];
            data[index] = temp;

            heapSortAsc(data, index - 1);
        }
    }

    /**
     * 初始化堆,找出最大的放在堆顶
     *
     * @param data
     * @param index
     */
    private static <T> void initHeapAsc(T[] data, int index) {
        int m = (index + 1) / 2;
        for (int i = 0; i < m; i++) {
            boolean flag = buildHeapAsc(data, index, i);
            //如果子节点之间有交换,就要重新开始
            if (flag) {
                i = -1;
            }
        }
    }

    /**
     * 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
     *
     * @param data
     * @param index
     * @param i
     * @return
     */
    private static <T> boolean buildHeapAsc(T[] data, int index, int i) {
        int lNode = 2 * i + 1;
        int rNode = 2 * i + 2;
        if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
            if (compare(data[i], data[lNode]) == -1) {
                T temp = data[i];
                data[i] = data[lNode];
                data[lNode] = temp;
                return true;
            } else {
                return false;
            }
        }
        //在根与两个孩子之间找出最大的那个值进行交换
        if (compare(data[i], data[lNode]) == -1) {
            if (compare(data[lNode], data[rNode]) == 1) {
                //交换根与左孩子的值
                T temp = data[i];
                data[i] = data[lNode];
                data[lNode] = temp;
                return true;
            } else {
                //交换根与右孩子的值
                T temp = data[i];
                data[i] = data[rNode];
                data[rNode] = temp;
                return true;
            }
        } else if (compare(data[i], data[rNode]) == -1) {
            //交换根与右孩子的值
            T temp = data[i];
            data[i] = data[rNode];
            data[rNode] = temp;
            return true;
        }
        return false;
    }

    /**
     * 堆排序Desc
     *
     * @param data 待排序数组
     */
    public static <T> void heapSortDesc(T[] data) {
        heapSortDesc(data, data.length - 1);
    }

    /**
     * 堆排序Desc
     *
     * @param data
     * @param index
     */
    private static <T> void heapSortDesc(T[] data, int index) {
        if (index > 0) {
            initHeapDesc(data, index);

            T temp = data[0];
            data[0] = data[index];
            data[index] = temp;

            heapSortDesc(data, index - 1);
        }
    }

    /**
     * 初始化堆,找出最大的放在堆顶
     *
     * @param data
     * @param index
     */
    private static <T> void initHeapDesc(T[] data, int index) {
        int m = (index + 1) / 2;
        for (int i = 0; i < m; i++) {
            boolean flag = buildHeapDesc(data, index, i);
            //如果子节点之间有交换,就要重新开始
            if (flag) {
                i = -1;
            }
        }
    }

    /**
     * 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
     *
     * @param data
     * @param index
     * @param i
     * @return
     */
    private static <T> boolean buildHeapDesc(T[] data, int index, int i) {
        int lNode = 2 * i + 1;
        int rNode = 2 * i + 2;
        if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
            if (compare(data[i], data[lNode]) == 1) {
                T temp = data[i];
                data[i] = data[lNode];
                data[lNode] = temp;
                return true;
            } else {
                return false;
            }
        }
        //在根与两个孩子之间找出最大的那个值进行交换
        if (compare(data[i], data[lNode]) == 1) {
            if (compare(data[lNode], data[rNode]) == -1) {
                //交换根与左孩子的值
                T temp = data[i];
                data[i] = data[lNode];
                data[lNode] = temp;
                return true;
            } else {
                //交换根与右孩子的值
                T temp = data[i];
                data[i] = data[rNode];
                data[rNode] = temp;
                return true;
            }
        } else if (compare(data[i], data[rNode]) == 1) {
            //交换根与右孩子的值
            T temp = data[i];
            data[i] = data[rNode];
            data[rNode] = temp;
            return true;
        }
        return false;
    }

    /**
     * 堆排序ASC
     *
     * @param data 待排序List
     */
    public static <T> void heapSortAsc(List<T> data) {
        heapSortAsc(data, data.size() - 1);
    }

    /**
     * 堆排序ASC
     *
     * @param data
     * @param index
     */
    private static <T> void heapSortAsc(List<T> data, int index) {
        if (index > 0) {
            initHeapAsc(data, index);

            T temp = data.get(0);
            data.set(0, data.get(index));
            data.set(index, temp);

            heapSortAsc(data, index - 1);
        }
    }

    /**
     * 初始化堆,找出最大的放在堆顶
     *
     * @param data
     * @param index
     */
    private static <T> void initHeapAsc(List<T> data, int index) {
        int m = (index + 1) / 2;
        for (int i = 0; i < m; i++) {
            boolean flag = buildHeapAsc(data, index, i);
            //如果子节点之间有交换,就要重新开始
            if (flag) {
                i = -1;
            }
        }
    }

    /**
     * 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
     *
     * @param data
     * @param index
     * @param i
     * @return
     */
    private static <T> boolean buildHeapAsc(List<T> data, int index, int i) {
        int lNode = 2 * i + 1;
        int rNode = 2 * i + 2;
        if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
            if (compare(data.get(i), data.get(lNode)) == -1) {
                T temp = data.get(i);
                data.set(i, data.get(lNode));
                data.set(lNode, temp);
                return true;
            } else {
                return false;
            }
        }
        //在根与两个孩子之间找出最大的那个值进行交换
        if (compare(data.get(i), data.get(lNode)) == -1) {
            if (compare(data.get(lNode), data.get(rNode)) == 1) {
                //交换根与左孩子的值
                T temp = data.get(i);
                data.set(i, data.get(lNode));
                data.set(lNode, temp);
                return true;
            } else {
                //交换根与右孩子的值
                T temp = data.get(i);
                data.set(i, data.get(rNode));
                data.set(rNode, temp);
                return true;
            }
        } else if (compare(data.get(i), data.get(rNode)) == -1) {
            //交换根与右孩子的值
            T temp = data.get(i);
            data.set(i, data.get(rNode));
            data.set(rNode, temp);
            return true;
        }
        return false;
    }

    /**
     * 堆排序Desc
     *
     * @param data 待排序List
     */
    public static <T> void heapSortDesc(List<T> data) {
        heapSortDesc(data, data.size() - 1);
    }

    /**
     * 堆排序Desc
     *
     * @param data
     * @param index
     */
    private static <T> void heapSortDesc(List<T> data, int index) {
        if (index > 0) {
            initHeapDesc(data, index);

            T temp = data.get(0);
            data.set(0, data.get(index));
            data.set(index, temp);

            heapSortDesc(data, index - 1);
        }
    }

    /**
     * 初始化堆,找出最大的放在堆顶
     *
     * @param data
     * @param index
     */
    private static <T> void initHeapDesc(List<T> data, int index) {
        int m = (index + 1) / 2;
        for (int i = 0; i < m; i++) {
            boolean flag = buildHeapDesc(data, index, i);
            //如果子节点之间有交换,就要重新开始
            if (flag) {
                i = -1;
            }
        }
    }

    /**
     * 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
     *
     * @param data
     * @param index
     * @param i
     * @return
     */
    private static <T> boolean buildHeapDesc(List<T> data, int index, int i) {
        int lNode = 2 * i + 1;
        int rNode = 2 * i + 2;
        if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
            if (compare(data.get(i), data.get(lNode)) == 1) {
                T temp = data.get(i);
                data.set(i, data.get(lNode));
                data.set(lNode, temp);
                return true;
            } else {
                return false;
            }
        }
        //在根与两个孩子之间找出最大的那个值进行交换
        if (compare(data.get(i), data.get(lNode)) == 1) {
            if (compare(data.get(lNode), data.get(rNode)) == -1) {
                //交换根与左孩子的值
                T temp = data.get(i);
                data.set(i, data.get(lNode));
                data.set(lNode, temp);
                return true;
            } else {
                //交换根与右孩子的值
                T temp = data.get(i);
                data.set(i, data.get(rNode));
                data.set(rNode, temp);
                return true;
            }
        } else if (compare(data.get(i), data.get(rNode)) == 1) {
            //交换根与右孩子的值
            T temp = data.get(i);
            data.set(i, data.get(rNode));
            data.set(rNode, temp);
            return true;
        }
        return false;
    }

    /**
     * 比较大小
     *
     * @param val1
     * @param val2
     * @return 1:val1>val2;0:val1=val2;-1:val1<val2
     */
    private static <T> int compare(T val1, T val2) {
        int rtn = 0;
        if (val1.getClass().getName().equals("java.lang.Integer")) {
            Integer v1 = (Integer) val1;
            Integer v2 = (Integer) val2;
            rtn = Integer.compare(v1, v2);
        } else if (val1.getClass().getName().equals("java.lang.Float")) {
            Float v1 = (Float) val1;
            Float v2 = (Float) val2;
            rtn = Float.compare(v1, v2);
        } else if (val1.getClass().getName().equals("java.lang.Double")) {
            Double v1 = (Double) val1;
            Double v2 = (Double) val2;
            rtn = Double.compare(v1, v2);
        } else if (val1.getClass().getName().equals("java.lang.Character")) {
            Character v1 = (Character) val1;
            Character v2 = (Character) val2;
            return Character.compare(v1, v2);
        } else if (val1.getClass().getName().equals("java.lang.String")) {
            String v1 = (String) val1;
            String v2 = (String) val2;
            return v1.compareTo(v2);
        }
        return rtn;
    }

    /**
     * 获取数组中最大值的位置
     *
     * @param data
     * @param left
     * @param right
     * @return
     */
    private static <T> int getMaxIndex(T[] data, int left, int right) {
        int index = left;
        T maxValue = data[left];
        for (int i = left + 1; i <= right; i++) {
            if (compare(data[i], maxValue) == 1) {
                maxValue = data[i];
                index = i;
            }
        }
        return index;
    }

    /**
     * 获取List中最大值的位置
     *
     * @param data
     * @param left
     * @param right
     * @return
     */
    private static <T> int getMaxIndex(List<T> data, int left, int right) {
        int index = left;
        T maxValue = data.get(left);
        for (int i = left + 1; i <= right; i++) {
            if (compare(data.get(i), maxValue) == 1) {
                maxValue = data.get(i);
                index = i;
            }
        }
        return index;
    }

    /**
     * 获取数组中最小值的位置
     *
     * @param data
     * @param left
     * @param right
     * @return
     */
    private static <T> int getMinIndex(T[] data, int left, int right) {
        int index = left;
        T minValue = data[left];
        for (int i = left + 1; i <= right; i++) {
            if (compare(data[i], minValue) == -1) {
                minValue = data[i];
                index = i;
            }
        }
        return index;
    }

    /**
     * 获取List中最小值的位置
     *
     * @param data
     * @param left
     * @param right
     * @return
     */
    private static <T> int getMinIndex(List<T> data, int left, int right) {
        int index = left;
        T minValue = data.get(left);
        for (int i = left + 1; i <= right; i++) {
            if (compare(data.get(i), minValue) == -1) {
                minValue = data.get(i);
                index = i;
            }
        }
        return index;
    }
}

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

package org.bond.test;

import java.util.Random;
import java.util.List;
import java.util.ArrayList;

import org.bond.sort.SortingAlgorithm;

public class Start {

    public static void main(String[] args) throws Exception {
        try {
            long beginTime = System.currentTimeMillis();

            //test1();
            test2();

            long endTime = System.currentTimeMillis();
            System.out.println("\r\n时间:" + (endTime - beginTime));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void test1() {
        Random rd = new Random();
        Integer[] data = new Integer[10];
        for (int i = 0; i < data.length; i++) {
            data[i] = rd.nextInt(100);
        }

        System.out.println("\r\n排序之前:");
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]);
            System.out.print(",");
        }

        SortingAlgorithm.mergeSortDesc(data);

        System.out.println("\r\n排序之后:");
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]);
            System.out.print(",");
        }
    }

    private static void test2() {
        Random rd = new Random();
        List<Integer> data = new ArrayList<Integer>();
        for (int i = 0; i < 10; i++) {
            data.add(rd.nextInt(100));
        }

        System.out.println("\r\n排序之前:");
        for (int i = 0; i < data.size(); i++) {
            System.out.print(data.get(i));
            System.out.print(",");
        }

        SortingAlgorithm.mergeSortDesc(data);

        System.out.println("\r\n排序之后:");
        for (int i = 0; i < data.size(); i++) {
            System.out.print(data.get(i));
            System.out.print(",");
        }
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值