Java 9种基本排列

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class SortDemo1 {

    // 1.插入排序:直接插入排序,二分法排序,希尔排序
    // (1).直接插入排序:从后往前比较插入(第一个数可以不用比较)
    // (2).二分法排序:取low.mid,hight,进行比较,当low>height时low或者height+1为插入点,low与要插入的数据之间的数据后移一位
    // (3).希尔排列:将数组分成length/2../2的小组,每个小组进行直接插入排序
    // 2.选择排序:简单选择排序,堆排序
    // (4).简单选择排序:每次找出最小值,然后放在最前面
    // (5).堆排序:利用二叉树的形式,从最后一个数开始比较,将最大的数往上推,每循环一次,最上面的数为最大,取出并用为排序的最后一个数替换(注意:此循环可以少比较一次,因为最后只剩两个数的时候也会进行比较,这时就已经替换了。所有只剩一个值时极为最大值。)
    // 3.交换排序:冒泡排序,快速排序
    // (6).冒泡排序:相邻两个数一次比较,大的数往下沉
    // (7).快速排序:取小组第一个数为基数,通过从后往前比较,将比基数小的数放在基数的右边,再通过从前往后比较,将比基数大的数放在基数的右边,只到左右两边比较完之后,将已基数为中点,将数组一分为二,利用递归,再次比较(递归)
    // 4.基数排序
    // (8).技术排列:从低位进行比较(与我们通常比较高位大小进行比较相反),利用10个(0-9共十个数)List存放数据
    // 5,归并排序
    // (9).归并排序:将数组一分为二,利用递归,最后分成一组一个,进行有序排列

    public static void main(String[] args) {
        ArrayList<Long> times = new ArrayList<Long>(); 
        int[] data;
        long start, end;
        data = getRandom();
        start = System.currentTimeMillis();
        // 直接插入排序
        start = System.currentTimeMillis();
        toStraightInsertionSort(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("直接插入排序: " + Arrays.toString(data));

        // 二分法排序
        data = getRandom();
        start = System.currentTimeMillis();
        toBinarySort(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("二分法排序: " + Arrays.toString(data));

        // 希尔排序
        data = getRandom();
        start = System.currentTimeMillis();
        toShellSort(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("希尔排序: " + Arrays.toString(data));

        System.out.println(
                "*************************************************************************************");
        // 直接插入排序
        data = getRandom();
        start = System.currentTimeMillis();
        toStraightInsertionSort1(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("直接插入排序: " + Arrays.toString(data));

        // 希尔排序
        data = getRandom();
        start = System.currentTimeMillis();
        toShellSort1(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("希尔排序: " + Arrays.toString(data));
        System.out.println(
                "*************************************************************************************");

        // 直接选择排序
        data = getRandom();
        start = System.currentTimeMillis();
        toSimpleSelectionSort(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("直接选择排序: " + Arrays.toString(data));

        // 堆排序
        data = getRandom();
        start = System.currentTimeMillis();
        toHeapSort(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("堆排序: " + Arrays.toString(data));

        // 冒泡排序
        data = getRandom();
        start = System.currentTimeMillis();
        toBubbleSort(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("冒泡排序: " + Arrays.toString(data));

        // 快速排序
        data = getRandom();
        start = System.currentTimeMillis();
        toQuickSort(data, 0, data.length - 1);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("快速排序: " + Arrays.toString(data));

        // 基数排序
        data = getRandom();
        start = System.currentTimeMillis();
        toRadixSort(data);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("基数排序: " + Arrays.toString(data));

        // 归并排序
        data = getRandom();
        start = System.currentTimeMillis();
        toMergeSort(data, 0, data.length - 1);
        end = System.currentTimeMillis();
        System.out.println("排序耗时:" + (end - start) + "ms");times.add((end - start));
        System.out.println("归并排序: " + Arrays.toString(data));

        System.out.println("###########################################");
        System.out.println("所有排序耗时表:"+times.toString());
    }

    /**
     * 直接插入排序
     * 
     * @param data
     */
    public static void toStraightInsertionSort(int[] data) {

        int temp;// 保存要插入的值
        for (int i = 1; i < data.length; i++) {
            // 从后往前进行比较并插入
            temp = data[i];
            int j;
            for (j = i - 1; j >= 0; j--) {
                if (temp < data[j]) {// 后移一位
                    data[j + 1] = data[j];
                } else {// 找到插入位置
                    break;
                }
            }
            // 插入值
            data[j + 1] = temp;
        }
    }

    /**
     * 二分法排序
     * 
     * @param data
     */
    public static void toBinarySort(int[] data) {
        int low, mid, height, temp;

        for (int i = 1; i < data.length; i++) {
            low = 0;
            height = i - 1;
            temp = data[i];// 保存待插入的值
            while (low <= height) {
                mid = (height + low) / 2;// 更新中间节点
                if (data[i] > data[mid]) {// 更新左节点
                    low = mid + 1;
                } else {
                    height = mid - 1;
                }
            }
            // 要插入的位置是low或者height+1
            // 数据往后移一位(low与i-1之间的数)
            for (int j = i - 1; j >= low; j--) {
                data[j + 1] = data[j];
            }
            // 插入值
            data[low] = temp;
        }

    }

    /**
     * 希尔排列
     * 
     * @param data
     */
    public static void toShellSort(int[] data) {
        int temp;
        for (int d = data.length / 2; d > 0; d /= 2) {

            for (int i = d; i < data.length; i++) {
                // 对每一小组的数据进行直接插入排列
                int j = i - d;
                temp = data[i];
                for (; j >= 0; j -= d) {
                    if (temp < data[j]) {// 往后移d位
                        data[j + d] = data[j];
                    } else {// 找到插入位置
                        break;
                    }

                }
                // 插入数据
                data[j + d] = temp;
            }
        }
    }

    /**
     * 直接插入排序
     * 
     * @param data
     */
    public static void toStraightInsertionSort1(int[] data) {
        // 直接插入就类似于每小组就一个
        straightInsertionSort(data, 1);
    }

    /**
     * 希尔排列
     * 
     * @param data
     */
    public static void toShellSort1(int[] data) {
        for (int d = data.length / 2; d > 0; d /= 2) {
            straightInsertionSort(data, d);
        }
    }

    /**
     * 将希尔与直接插入相同代码
     * 
     * @param data
     * @param d
     */
    public static void straightInsertionSort(int[] data, int d) {
        int temp;
        for (int i = d; i < data.length; i++) {
            // 对每一小组的数据进行直接插入排列
            int j = i - d;
            temp = data[i];
            for (; j >= 0; j -= d) {
                if (temp < data[j]) {// 往后移d位
                    data[j + d] = data[j];
                } else {// 找到插入位置
                    break;
                }

            }
            // 插入数据
            data[j + d] = temp;
        }
    }

    /**
     * 简单选择排序
     * 
     * @param data
     */
    public static void toSimpleSelectionSort(int[] data) {
        int min, index, temp;
        for (int i = 0; i < data.length; i++) {
            min = data[i];
            temp = data[i];
            index = i;
            for (int j = i; j < data.length; j++) {
                if (min > data[j]) {// 更新最小值和记录最小值的下标
                    min = data[j];
                    index = j;

                }
            }
            // 将最小值与放在i位置互换
            data[i] = data[index];
            data[index] = temp;
        }

    }

    /**
     * 堆排序
     * 
     * @param data
     */
    public static void toHeapSort(int[] data) {

        int f, left, right, index, last;// 父节点,左右节点,正在比较的推的最后一个节点,所有未排列的最后一个节点
        for (int i = 0; i < data.length - 1; i++) {// 二叉树的格式,最后堆至少是两个,所以循环次数-1,
            last = data.length - 1 - i;
            index = last;
            f = (index - 1) / 2;
            for (; f >= 0; f--) {
                left = f * 2 + 1;
                if (left <= index) {// 左节点要小于比较的最后一个节点
                    if (left < index) {// 此时有右节点
                        right = left + 1;
                        if (data[left] > data[right]) {// 左节点值大于右节点值,二者互换
                            swap(data, left, right);
                        }
                        if (data[f] < data[right]) {// 右节点的值大于父节点的值,二者互换数据
                            swap(data, right, f);
                        }
                    } else {// 没有右节点,
                        if (data[left] > data[f]) {// 左节点的值大于父节点的值,二者进行交换
                            swap(data, left, f);
                        }
                    }
                }
                // 比较下一个节点值,更新比较堆的最后一个值,此时一定存在右节点,及index = 右节点的值
                index = (f - 1) * 2 + 2;
            }
            swap(data, 0, last);
        }
    }

    /**
     * 指定下标数据互换
     * 
     * @param data
     * @param i
     * @param j
     */
    private static void swap(int[] data, int i, int j) {
        int temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }

    /**
     * 冒泡排序
     * 
     * @param data
     */
    public static void toBubbleSort(int[] data) {
        int temp;
        for (int i = 0; i < data.length - 1; i++) {
            for (int j = 0; j < data.length - i - 1; j++) {
                if (data[j] > data[j + 1]) {// 相邻两个数进行比较,大的往下沉
                    temp = data[j];
                    data[j] = data[j + 1];
                    data[j + 1] = temp;
                }
            }
        }
    }

    /**
     * 快速排序: 利用递归
     * 
     * @param data
     * @param low
     * @param height
     */
    public static void toQuickSort(int[] data, int low, int height) {
        int l = low, h = height, temp;
        if (l < h) {
            temp = data[low];
            while (l < h) {
                // 从后往前查找小于temp的值
                while (l < h && temp <= data[h]) {
                    h--;
                }
                // 找到小于temp的值
                if (l < h) {
                    data[l++] = data[h];
                }
                // 从前往后查找比temp大的值
                while (l < h && temp >= data[l]) {
                    l++;
                }
                // 找到大于temp的值
                if (l < h) {
                    data[h--] = data[l];
                }
            }
            data[l] = temp;
            toQuickSort(data, low, l);
            toQuickSort(data, l + 1, height);
        }
    }

    /**
     * 基数排序
     * 
     * @param data
     */
    public static void toRadixSort(int[] data) {

        int times = 0, max = data[0];
        // 求出最大值,便于得出比较次数(最大位数)
        for (int i = 1; i < data.length; i++) {
            if (max < data[i]) {
                max = data[i];
            }
        }
        // 求出位数
        while (max > 0) {
            max /= 10;
            times++;
        }
        // 生成10个List
        ArrayList<ArrayList<Integer>> queueList = new ArrayList<ArrayList<Integer>>();
        for (int i = 0; i < 10; i++) {
            ArrayList<Integer> item = new ArrayList<Integer>();
            queueList.add(item);
        }
        for (int i = 0; i < times; i++) {
            // 分配
            for (int j = 0; j < data.length; j++) {
                int x = data[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
                ArrayList<Integer> item = queueList.get(x);
                item.add(data[j]);
                queueList.set(x, item);
            }
            // 更新数组
            int count = 0;
            for (int k = 0; k < 10; k++) {
                while (queueList.get(k).size() > 0) {
                    data[count] = queueList.get(k).get(0);
                    queueList.get(k).remove(0);
                    count++;
                }
            }
        }
    }

    /**
     * 归并排序:利用递归 一分为二,然后进行有序排序
     * 
     * @param data
     * @param low
     * @param height
     */
    public static void toMergeSort(int[] data, int low, int height) {

        int mid;
        if (low < height) {
            mid = (low + height) / 2;
            toMergeSort(data, low, mid);
            toMergeSort(data, mid + 1, height);
            toOrderlySort(data, low, mid, height);
        }

    }

    /**
     * 有序排序
     * 
     * @param data
     * @param low
     * @param mid
     * @param height
     */
    private static void toOrderlySort(int[] data, int low, int mid, int height) {
        int i = low, j = mid + 1, n = mid, m = height;// 将data数组以low,mid,height为界限分成两个部分
        // 用于更新数据
        int count = 0;
        int len = height - low + 1;
        int[] temp = new int[len];
        // 先比较二个
        while (i <= n && j <= m) {
            if (data[i] < data[j]) {
                temp[count++] = data[i++];
            } else {
                temp[count++] = data[j++];
            }
        }
        // 只剩一个数组数据没有对比完
        while (i <= n) {
            temp[count++] = data[i++];
        }
        while (j <= m) {
            temp[count++] = data[j++];
        }
        // 更新数组数据
        for (int k : temp) {
            data[low++] = k;
        }
    }

    private static int[] getRandom() {
        Random random = new Random();
        int len = 100000;
        int[] data = new int[len];
        for (int i = 0; i < len; i++) {
            data[i] = random.nextInt(len);
        }
        System.out.println("原始数据 :"+Arrays.toString(data));
        return data;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值