Java-Study_04 Array 冒泡排序

import java.util.Arrays;

public class 排序算法 {
    public static void main(String[] args) throws Exception {
        int[] nums = {1,4,3,2,5,8,6,7,9,10,12,11};
        System.out.println(Arrays.toString(test1(nums))); //冒泡排序
        System.out.println(Arrays.toString(test2(nums))); //选择排序
        System.out.println(Arrays.toString(test3(nums))); //插入排序
        System.out.println(Arrays.toString(test4(nums))); //希尔排序
        System.out.println(Arrays.toString(test5(nums))); //并归排序
        System.out.println(Arrays.toString(test6(nums))); //快速排序
        System.out.println(Arrays.toString(test7(nums))); //堆排序
        System.out.println(Arrays.toString(test8(nums))); //计数排序
        System.out.println(Arrays.toString(test9(nums))); //桶排序
        System.out.println(Arrays.toString(test10(nums))); //基数排序
    }
    //TODO 冒泡排序
    public static int[] test1(int[] arr) {
        int len = arr.length;
        for (int i = 0; i < len - 1; i++) {
            for (int j = 0; j < len - 1 - i; j++) {
                if (arr[j] > arr[j+1]) {        // 相邻元素两两对比
                    int temp = arr[j+1];        // 元素交换
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }

    //TODO 选择排序
    public static int[] test2(int[] arr) {
        int len = arr.length;
        int minIndex, temp;
        for (int i = 0; i < len - 1; i++) {
            minIndex = i;
            for (int j = i + 1; j < len; j++) {
                if (arr[j] < arr[minIndex]) {     // 寻找最小的数
                    minIndex = j;                 // 将最小数的索引保存
                }
            }
            temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
        return arr;
    }

    //TODO 插入排序
    public static int[] test3(int[] arr) {
        int len = arr.length;
        int preIndex, current;
        for (int i = 1; i < len; i++) {
            preIndex = i - 1;
            current = arr[i];
            while(preIndex >= 0 && arr[preIndex] > current) {
                arr[preIndex+1] = arr[preIndex];
                preIndex--;
            }
            arr[preIndex+1] = current;
        }
        return arr;
    }

    //TODO 希尔排序
    public static int[] test4(int[] arr) {
        int length = arr.length;
        int temp;
        for (int step = length / 2; step >= 1; step /= 2) {
            for (int i = step; i < length; i++) {
                temp = arr[i];
                int j = i - step;
                while (j >= 0 && arr[j] > temp) {
                    arr[j + step] = arr[j];
                    j -= step;
                }
                arr[j + step] = temp;
            }
        }
        return arr;
    }

    //TODO 并归排序
    public static int[] test5(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        if (arr.length < 2) {
            return arr;
        }
        int middle = (int) Math.floor(arr.length / 2);

        int[] left = Arrays.copyOfRange(arr, 0, middle);
        int[] right = Arrays.copyOfRange(arr, middle, arr.length);

        return merge(test5(left), test5(right));
    }

    protected static int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        int i = 0;
        while (left.length > 0 && right.length > 0) {
            if (left[0] <= right[0]) {
                result[i++] = left[0];
                left = Arrays.copyOfRange(left, 1, left.length);
            } else {
                result[i++] = right[0];
                right = Arrays.copyOfRange(right, 1, right.length);
            }
        }

        while (left.length > 0) {
            result[i++] = left[0];
            left = Arrays.copyOfRange(left, 1, left.length);
        }

        while (right.length > 0) {
            result[i++] = right[0];
            right = Arrays.copyOfRange(right, 1, right.length);
        }

        return result;
    }

    //TODO 快速排序
    public static int[] test6(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        return quickSort(arr, 0, arr.length - 1);
    }

    private static int[] quickSort(int[] arr, int left, int right) {
        if (left < right) {
            int partitionIndex = partition(arr, left, right);
            quickSort(arr, left, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, right);
        }
        return arr;
    }

    private static int partition(int[] arr, int left, int right) {
        // 设定基准值(pivot)
        int pivot = left;
        int index = pivot + 1;
        for (int i = index; i <= right; i++) {
            if (arr[i] < arr[pivot]) {
                swap1(arr, i, index);
                index++;
            }
        }
        swap1(arr, pivot, index - 1);
        return index - 1;
    }

    private static void swap1(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    //TODO 堆排序
    public static int[] test7(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        int len = arr.length;

        buildMaxHeap(arr, len);

        for (int i = len - 1; i > 0; i--) {
            swap2(arr, 0, i);
            len--;
            heapify(arr, 0, len);
        }
        return arr;
    }

    private static void buildMaxHeap(int[] arr, int len) {
        for (int i = (int) Math.floor(len / 2); i >= 0; i--) {
            heapify(arr, i, len);
        }
    }

    private static void heapify(int[] arr, int i, int len) {
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;

        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }

        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap2(arr, i, largest);
            heapify(arr, largest, len);
        }
    }

    private static void swap2(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    //TODO 计数排序
    public static int[] test8(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        int maxValue = getMaxValue(arr);

        return countingSort(arr, maxValue);
    }

    private static int[] countingSort(int[] arr, int maxValue) {
        int bucketLen = maxValue + 1;
        int[] bucket = new int[bucketLen];

        for (int value : arr) {
            bucket[value]++;
        }

        int sortedIndex = 0;
        for (int j = 0; j < bucketLen; j++) {
            while (bucket[j] > 0) {
                arr[sortedIndex++] = j;
                bucket[j]--;
            }
        }
        return arr;
    }

    private static int getMaxValue(int[] arr) {
        int maxValue = arr[0];
        for (int value : arr) {
            if (maxValue < value) {
                maxValue = value;
            }
        }
        return maxValue;
    }


    //TODO 桶排序

    public static int[] test9(int[] arr) {

        // 遍历原始数组,找到数组中的最大值
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }

        // 创建一个下标为原始数组中最大值的桶数组,该桶数组的下标代表元素,该数组下标所对应的值代表这个值出现的次数

        int[] bucketArray = new int[max + 1];

        // 再次遍历原始数组,得到原数组中存在的各个元素,以及出现的次数
        for (int i = 0; i < arr.length; i++) {
            bucketArray[arr[i]]++;
        }

        // 遍历桶数组,外层循环从桶的第一位开始(即下表为零);内层循环遍历桶数组中下标为i的值出现的次数
        int index = 0;
        for (int i = 0; i < bucketArray.length; i++) {
            for (int j = 0; j < bucketArray[i]; j++) {
                arr[index++] = i;
            }
        }
        return arr;
    }

    //TODO 基数排序
    public static int[] test10(int[] arr) {
        // 假定arr[0] 是最大数
        // 1. 通过遍历arr, 找到数组中真正最大值
        // 2. 目的是确定要进行多少轮排序
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        // 计算最大数字是几位数
        int maxLength = (max + "").length();
        // 定义一个二维数组, 就是10个桶
        // 1. 该二维数组有10个一维数组 0-9
        // 2. 为了防止溢出,每个一维数组(桶),大小定为 arr.length
        // 3. 很明确, 基数排序是空间换时间
        int[][] bucket = new int[10][arr.length];
        // 用于记录在每个桶中,实际存放了多少个数据,这样才能正确的取出
        int[] bucketElementCounts = new int[10];
        // 根据最大长度的数决定比较的次数
        // 1. 大循环的次数就是 最大数有多少位,前面分析过
        // 2. n = 1, n *= 10 是为了每轮循环排序时,分别求出各个元素的 个位,十位,百位,千位 ...
        //    就是一个小算法
        // 3. 这个基础排序,完全可以使用 冒泡分步写代码来完成,比较简单!!
        for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
            // 把每一个数字分别计算本轮循环的位数的值,比如第1轮是个位...
            for (int j = 0; j < arr.length; j++) {
                // 计算
                int digitOfElement = arr[j] / n % 10;
                // 把当前遍历的数据放入指定的数组中
                bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
                // 记录数量
                bucketElementCounts[digitOfElement]++;
            }
            // 记录取的元素需要放的位置
            int index = 0;
            // 把各个桶中(10个桶)存放的数字取出来, 放入到arr中
            for (int k = 0; k < bucketElementCounts.length; k++) {
                // 如果这个桶中,有数据才取,没有数据就不取了
                if (bucketElementCounts[k] != 0) {
                    // 循环取出元素
                    for (int l = 0; l < bucketElementCounts[k]; l++) {
                        // 取出元素
                        arr[index++] = bucket[k][l];
                    }
                    // 把这个桶的对应的记录的数据个数置为0,注意,桶本身数据(前面存的数据还在)
                    bucketElementCounts[k] = 0; //
                }
            }
        }
        return arr;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值