Java十大排序算法实现

十大排序算法–知乎
十大排序算法–菜鸟教程
在这里插入图片描述
在这里插入图片描述

import java.util.ArrayList;
import java.util.Collections;

public class Sort {
    public static void main(String[] args) {

    }
    // 1、冒泡排序
    // 从最后一个索引位置开始,每次确定一个位置的数,保证后半段有序
    // 第二层循环是从最前面一个一个比较,直到有序的位置
    public static void bubbleSort(int[] nums){
        for(int i = nums.length - 1; i > 0; i--){
            for(int j = 0; j < i; j++){
                if(nums[j] > nums[j + 1]){
                    int tmp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = tmp;
                }
            }
        }
    }
    // 1-2、冒泡排序优化
    // 在冒泡排序的基础上增加一个标志位,如果前一轮没有进行交换,说明数组已经有序
    public static void bubbleSortPro(int[] nums){
        for(int i = nums.length - 1; i > 0; i--){
            boolean flag = false;
            for(int j = 0; j < i; j++){
                if(nums[j] > nums[j + 1]){
                    int tmp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = tmp;
                    flag = true;
                }
            }
            if(!flag){
                break;
            }
        }
    }

    // 2、选择排序
    // 依次找出当前无序的里面最小的,放到有序半段的末尾,保证前半段有序
    public static void selectionSort(int[] nums){
        for(int i = 0; i < nums.length - 1; i++){
            int min = i;
            for(int j = i + 1; j < nums.length; j++){
                if(nums[j] < nums[min]){
                    min = j;
                }
            }
            if(i != min){
                int tmp = nums[i];
                nums[i] = nums[min];
                nums[min] = tmp;
            }
        }
    }

    // 3、插入排序
    // 从第二个元素开始,在有序子数组中查找该元素的合适位置并插入
    public static void insertionSort(int[] nums){
        for(int i = 1; i < nums.length; i++){
            int tmp = nums[i];

            int j = i;
            while(j > 0 && tmp < nums[j - 1]){
                nums[j] = nums[j - 1];
                j--;
            }
            if(j != i){
                nums[j] = tmp;
            }
        }
    }

    // 4、希尔排序
    // 插入排序的改进版本,增加了步长的
    // 将整个待排序的序列分割成若干子序列并分别进行插入排序,基本有序后再整体依次插入排序
    // 通过不同长度的step,每次保证局部有序,逐步缩短step,然后最终实现整体有序
    public static void shellSort(int[] nums) {
        for (int step = nums.length / 2; step >= 1; step /= 2) {
            for (int i = step; i < nums.length; i++) {
                int temp = nums[i];
                int j = i - step;
                while (j >= 0 && nums[j] > temp) {
                    nums[j + step] = nums[j];
                    j -= step;
                }
                nums[j + step] = temp;
            }
        }
    }

    // 5、归并排序
    // 分治算法的经典应用
    public static void mergeSort(int[] nums){
        int[] tmp = new int[nums.length];
        internalMergeSort(nums, tmp, 0, nums.length - 1);
    }
    private static void internalMergeSort(int[] nums, int[] tmp, int left, int right) {
        if(left < right){
            int mid = (left + right) >>> 1;
            internalMergeSort(nums, tmp, left, mid);
            internalMergeSort(nums, tmp, mid + 1, right);
            mergeSortedArray(nums, tmp, left, mid, right);
        }
    }
    private static void mergeSortedArray(int[] nums, int[] tmp, int left, int mid, int right) {
        int i = left, j = mid + 1, k = 0;
        while(i <= mid && j <= right){
            tmp[k++] = nums[i] <= nums[j] ? nums[i++] : nums[j++];
        }
        while(i <= mid){
            tmp[k++] = nums[i++];
        }
        while(j <= right){
            tmp[k++] = nums[j++];
        }
        for (int l = 0; l < k; l++) {
            nums[left + l] = tmp[l];
        }
    }

    // 6、快排
    public static void quickSort(int[] nums){
        qSort(nums, 0, nums.length - 1);
    }
    private static void qSort(int[] nums, int lo, int hi) {
        if(lo >= hi){
            return;
        }
        int m = partition(nums, lo, hi);
        qSort(nums, lo, m - 1);
        qSort(nums, m, hi);
    }
    private static int partition(int[] nums, int lo, int hi){
        int i = lo, j = hi + 1;
        while(true){
            while(++i <= hi && nums[i] < nums[lo]);
            while(--j >= lo && nums[j] > nums[lo]);
            if(i >= j){
                break;
            }
            swap(nums, i, j);
        }
        swap(nums, lo, j);
        return i;
    }
    private static void swap(int[] nums, int lo, int j) {
        int tmp = nums[lo];
        nums[lo] = nums[j];
        nums[j] = tmp;
    }

    // 7、堆排序
    public class ArrayHeap {
        private int[] arr;
        public ArrayHeap(int[] arr) {
            this.arr = arr;
        }
        private int getParentIndex(int child) {
            return (child - 1) / 2;
        }
        private int getLeftChildIndex(int parent) {
            return 2 * parent + 1;
        }
        private void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        /**
         * 调整堆。
         */
        private void adjustHeap(int i, int len) {
            int left, right, j;
            left = getLeftChildIndex(i);
            while (left <= len) {
                right = left + 1;
                j = left;
                if (j < len && arr[left] < arr[right]) {
                    j++;
                }
                if (arr[i] < arr[j]) {
                    swap(arr, i, j);
                    i = j;
                    left = getLeftChildIndex(i);
                } else {
                    break; // 停止筛选
                }
            }
        }
        /**
         * 堆排序。
         * */
        public void sort() {
            int last = arr.length - 1;
            // 初始化最大堆
            for (int i = getParentIndex(last); i >= 0; --i) {
                adjustHeap(i, last);
            }
            // 堆调整
            while (last >= 0) {
                swap(arr, 0, last--);
                adjustHeap(0, last);
            }
        }
    }

    // 8、计数排序
    public static void countSort(int[] a, int max, int min) {
        int[] b = new int[a.length];//存储数组
        int[] count = new int[max - min + 1];//计数数组

        for (int num = min; num <= max; num++) {
            //初始化各元素值为0,数组下标从0开始因此减min
            count[num - min] = 0;
        }

        for (int i = 0; i < a.length; i++) {
            int num = a[i];
            count[num - min]++;//每出现一个值,计数数组对应元素的值+1
        }

        for (int num = min + 1; num <= max; num++) {
            //加总数组元素的值为计数数组对应元素及左边所有元素的值的总和
            count[num - min] += a[num - min - 1];
        }

        for (int i = 0; i < a.length; i++) {
            int num = a[i];//源数组第i位的值
            int index = count[num - min] - 1;//加总数组中对应元素的下标
            b[index] = num;//将该值存入存储数组对应下标中
            count[num - min]--;//加总数组中,该值的总和减少1。
        }

        //将存储数组的值一一替换给源数组
        for(int i=0;i<a.length;i++){
            a[i] = b[i];
        }
    }

    // 9、桶排序
    public static void bucketSort(int[] arr){
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for(int i = 0; i < arr.length; i++){
            max = Math.max(max, arr[i]);
            min = Math.min(min, arr[i]);
        }
        //桶数
        int bucketNum = (max - min) / arr.length + 1;
        ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
        for(int i = 0; i < bucketNum; i++){
            bucketArr.add(new ArrayList<Integer>());
        }
        //将每个元素放入桶
        for(int i = 0; i < arr.length; i++){
            int num = (arr[i] - min) / (arr.length);
            bucketArr.get(num).add(arr[i]);
        }
        //对每个桶进行排序
        for(int i = 0; i < bucketArr.size(); i++){
            Collections.sort(bucketArr.get(i));
        }
        System.out.println(bucketArr.toString());
    }
}



/**
 * 10、基数排序
 * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN/q/e98fa9
 */
public class RadixSort implements IArraySort {

    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        int maxDigit = getMaxDigit(arr);
        return radixSort(arr, maxDigit);
    }

    /**
     * 获取最高位数
     */
    private int getMaxDigit(int[] arr) {
        int maxValue = getMaxValue(arr);
        return getNumLenght(maxValue);
    }

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

    protected int getNumLenght(long num) {
        if (num == 0) {
            return 1;
        }
        int lenght = 0;
        for (long temp = num; temp != 0; temp /= 10) {
            lenght++;
        }
        return lenght;
    }

    private int[] radixSort(int[] arr, int maxDigit) {
        int mod = 10;
        int dev = 1;

        for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
            // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
            int[][] counter = new int[mod * 2][0];

            for (int j = 0; j < arr.length; j++) {
                int bucket = ((arr[j] % mod) / dev) + mod;
                counter[bucket] = arrayAppend(counter[bucket], arr[j]);
            }

            int pos = 0;
            for (int[] bucket : counter) {
                for (int value : bucket) {
                    arr[pos++] = value;
                }
            }
        }

        return arr;
    }

    /**
     * 自动扩容,并保存数据
     *
     * @param arr
     * @param value
     */
    private int[] arrayAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值