10大排序算法java实现(更新中)

java实现10大排序算法

冒泡排序


    /**
     * 冒泡排序
     * @param arr
     */
    public static void bubbleSort(int[] arr){
        for (int i = 0; i < arr.length-1; i++) {

            for (int j = 0; j < arr.length-i-1; j++) {

                if (arr[j]>arr[j+1]){//顺序
                    //交换
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }

选择排序

    /**
     * 选择排序
     * @param arr
     */
    public static void selectionSort(int[] arr) {
        int index ;
        for (int i = 0; i < arr.length-1; i++) {//遍历的次数
            index = i;
            for (int j = i+1; j < arr.length; j++) {
                if (arr[index]>arr[j]){
                    index=j;//找小的,把小的角标给index
                }
            }
            //最后进行交换到第i个
            int temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;

        }
    }

插入排序

 /**
     * 插入排序:类似于打扑克整理牌时(从小到大排序,通过与前者一一比较确定其位置,)
     * 也可以类比成麻将(一万到九万乱序,从左开始与其前者进行比较,比前者小,前者就往右移空出位置。。。
     *
     * @param arr
     */
    public static void insertSort(int[] arr){
        for (int i = 1; i < arr.length; i++) {//次数
            int j = i-1;
            int target = arr[i];//当前拿着的数据
            while (j > -1 && target<arr[j]){
                //往右移!能符合条件:
                arr[j+1] = arr[j];
                j--;
            }
            arr[j+1] = target;//将拿着的元素插进去
        }
    }

快速排序

思想

 /**
     * 快速排序,找一个基准,左右两个指针,左指针往右走,走到大于基准的地方停下来
     * 右指针往左走,走到小于基准的地方停下来,然后这两个数交换,
     * 重复上述动作,直到左右指针拥抱
     * (左指针会走到大与基准的地方停下,所以基准要和左指针-1的地方交换)
     * 基准:(可以使用三元取中)
     * @param arr
     * @param small
     * @param big
     */
    public static void QUICKSORT(int[] arr, int small, int big){
        if (small > big) {//终止条件
            return;
        }
        int compare = arr[small];//基准值,用来比较
        int p = small;//基准指针
        int left = small+1;//最左边
        int right = big;//最右边
        while (left <= right){
            while (left <= right && arr[left]<=compare){//找(大的数)位置停
                left++;
            }
            while (left <= right && arr[right]>compare){//找(小的数)位置停
                right--;
            }

            //都停下来之后进行交换
            if (left < right) {//最后一次不用交换
                int temp = arr[left];
                arr[left] = arr[right];
                arr[right] = temp;
            }
        }
        //final
        //把标准p换到 right 的位置,进行一波交换 【p,A,B,C,right{<compare},left{>compare},D,E,F】
        int temp = arr[p];
        arr[p] = arr[right];
        arr[right] = temp;
        //递归调用===从bigger分开;
        QUICKSORT(arr,small,right-1);
        QUICKSORT(arr,right+1,big);
    }

希尔排序


 /**
     * 把数组按照间隔i挖出几组数比如【1,5,9,13】【2,6,10,14】【3,7,11,15】......i = 4
     * 组内进行比较排序
     * 再以(i/2)的间隔挖出几组数比如【1,3,5,7】【2,4,6,8】......i = 2
     * 以此类推直至 i = 1 进行最后的排序
     * @param arr
     */
    public static void shellSort(int[] arr){
        for (int i = arr.length/2; i > 0; i/=2) {  //间隔i,每次减半
            for (int j = i; j < arr.length; j++) {
                int x = arr[j];  // x为将要插入的元素
                int in = j-i;   //前面已经排好序元素最后一个
                while(in > -1 && arr[in]>x){//元素依次往后移,留出合适位置
                    arr[in+i]=arr[in];//类似于插入排序
                    in -= i;
                }
                arr[in+i]=x;
            }
        }
    }

/**
     * 归并排序
     * @param arr
     */
    public static void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process(arr, 0, arr.length - 1);
    }

    //该方法表示将arr数组的L到R位置上的数字变为有序的
    public static void process(int[] arr, int L, int R) {
        //俗称base case,即划分到什么程度时,就不需要再继续划分了
        if (L == R) {
            return;
        }
        //求中间位置,L到mid是左侧递归部分的数据,mid+1到R是右侧递归部分的数据
        int mid = L + ((R - L) >> 1);
        //左右两侧进行递归拆分
        process(arr, L, mid);
        process(arr, mid + 1, R);
        //再将arr中的左右两部分合并为有序的,L到mid为左侧部分,mid+1到R是右侧
        //递归部分的数据,所以位置信息传三个参数就行,不用传mid+1参数
        merge(arr, L, mid, R);
    }

    //
    public static void merge(int[] arr, int L, int M, int R) {
        //准备辅助数组,存放排序后的数据
        int[] help = new int[R - L + 1];
        int i = 0;
        //左侧数据起始位置
        int p1 = L;
        //右侧数据起始位置
        int p2 = M + 1;
        //左右两侧都没遍历完,即p1、p2都没越界
        while (p1 <= M && p2 <= R) {
            //将左右部分的数据进行比较,小的数据存放到辅助数组,
            //然后help和添加到辅助数组的部分指针(p1或p2)进行右移
            help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
        }
        //当跳出wile循环,代表左或右某个部分已经遍历完了,然后将未
        //遍历完的追加到辅助数组尾部,下面的两个while循环只能有一个执行
        while (p1 <= M) {
            help[i++] = arr[p1++];
        }
        while (p2 <= R) {
            help[i++] = arr[p2++];
        }
        //将辅助数组中的数据追加到原arr数组中
        for (i = 0; i < help.length; i++) {
            arr[L + i] = help[i];
        }
    }
/**
     * 计数排序
     * @param a
     */
    static void CountSort(int[] a) {
        int max = a[0];
        int min = a[0];
        for (int e : a) {
            if (e > max) {
                max = e;
            }
        }
        for (int e : a) {
            if (e < min) {
                min = e;
            }
        }
        int[] helper = new int[max - min + 1];
        for (int e : a) {
            helper[e-min]++;//减去最小值。
        }
        int current = 0;//数据回填的位置[指针]
        for (int i = 0; i < helper.length; i++) {
            while (helper[i] > 0) {
                a[current++] = i+min;//(i为元素 还要加上最小值)
                helper[i]--;
            }
        }
    }
/**
     * 堆排序
     * @param sourceArray
     * @return
     * @throws Exception
     */
    public int[] HeapSort(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--) {
            swap(arr, 0, i);
            len--;
            heapify(arr, 0, len);
        }
        return arr;
    }

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

    private 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) {
            swap(arr, i, largest);
            heapify(arr, largest, len);
        }
    }

    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
public static void bucketSort(int[] arr){
        /*计算最大值与最小值*/
        int max = 0;
        int min = 0;
        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组织对应的桶*/
        List<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));
        }
        /*将桶中的元素赋值到原始数组arr*/
        for(int i = 0,index = 0; i < bucketArr.size(); i++){
            for(int j = 0; j < bucketArr.get(i).size(); j++){
                arr[index++] = bucketArr.get(i).get(j);
            }
        }

    }
/**
     * 基数排序
     * @param array
     * @param digit
     */
    static void radixSort(int[] array, int digit) {
        /*此处桶数之所以取10,是因为数字0-9总共是十个数字,因此每趟比较时,分为10个桶*/
        int radix = 10;
        int i = 0, j = 0;
        /*存放各个桶的数据统计个数*/
        int[] count = new int[radix];
        int[] bucket = new int[array.length];
        /*按照从低位到高位的顺序执行排序过程*/
        for (int d = 1; d <= digit; d++) {
            /*置空各个桶的数据统计*/
            for (i = 0; i < radix; i++) {
                count[i] = 0;
            }
            /*统计各个桶将要装入的数据个数*/
            for (i = 0; i <array.length; i++) {
                j = getDigit(array[i], d);
                count[j]++;
            }
            /*count[i]表示第i个桶的右边界索引*/
            for (i = 1; i < radix; i++) {
                count[i] = count[i] + count[i - 1];
            }
            /*将数据依次装入桶中,这里要从右向左扫描,保证排序稳定性*/
            for (i = array.length-1; i >= 0; i--) {
                j = getDigit(array[i], d);
                /*求出元素的第k位的数字, 例如:576的第3位是5*/
                bucket[count[j] - 1] = array[i];
                /*放入对应的桶中,count[j]-1是第j个桶的右边界索引,对应桶的装入数据索引减一*/
                count[j]--; //
            }
            /*将已分配好的桶中数据再倒出来,此时已是对应当前位数有序的表*/
            for (i = 0, j = 0; i < array.length; i++, j++) {
                array[i] = bucket[j];
            }
        }
    }

    /*获取x这个数的d位数上的数字,比如获取123的1位数,结果返回3*/
    static int getDigit(int num, int d) {
        /*本实例中的最大数是百位数,所以只要到100就可以了*/
        int digit[] = {1, 10, 100};
        return ((num/digit[d-1]) % 10);
    }
//更新中。。。

如有错误欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值