javaSE基础知识——day13 八种排序冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、基数排序

冒泡排序

冒泡排序:元素两两比较,大的往后放,经过一轮比较后,那么最大的元素就会出现在最后面。

案例:

import java.util.Arrays;

public class ArraySortDemo {
    public static void main(String[] args) {
        //冒泡排序:元素两两比较,大的往后放,经过一轮比较后,那么最大的元素就会出现在最后面。
        //定义原始数组
        
        int[] arr = {24, 69, 80, 57, 13,1,4,6,-1};
        //tuiDao(arr);

        for (int j = 0; j <arr.length-1; j++) {
            for (int i = 0; i < arr.length - 1-j; i++) {
                //比较大小,把大的往后放
                if (arr[i] > arr[i + 1]) {
                    int t = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = t;
                }

            }
        }


        System.out.println(Arrays.toString(arr));

        
    }

    private static void tuiDao(int[] arr) {
        //第一轮比较4次
        for (int i = 0; i < arr.length-1; i++) {
            //比较大小,把大的往后放
            if(arr[i]>arr[i+1]){
                int t=arr[i];
                arr[i]=arr[i+1];
                arr[i + 1]=t;
            }

        }
        //第二轮比较3次
        for (int i = 0; i < arr.length - 1-1; i++) {
            //比较大小,把大的往后放
            if (arr[i] > arr[i + 1]) {
                int t = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = t;
            }

        }
        //第三比较2次
        for (int i = 0; i < arr.length - 1 - 1-1; i++) {
            //比较大小,把大的往后放
            if (arr[i] > arr[i + 1]) {
                int t = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = t;
            }

        }

        //第四轮比较
        for (int i = 0; i < arr.length - 1 - 1 - 1-1; i++) {
            //比较大小,把大的往后放
            if (arr[i] > arr[i + 1]) {
                int t = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = t;
            }

        }
    }
}


选择排序

每次拿一个元素,跟他后面的元素,挨个去比,小的往前放,经过一轮比较后,那么最小元素就会放在最前面去

案例:

import java.util.Arrays;
public class ArraySortDemo2 {
    public static void main(String[] args) {
        //选择排序:每次拿一个元素,跟他后面的元素,挨个去比,小的往前放,经过一轮比较后,那么最小元素就会放在最前面去
        int[] arr = {24, 69, 80, 57, 13, 4, 6, 90, -1};
        //  tuiDao(arr);
        for (int index = 0; index < arr.length - 1; index++) {
            for (int i = 1 + index; i < arr.length; i++) {
                if (arr[index] > arr[i]) {
                    swapValue(arr, index, i);
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }

    private static void tuiDao(int[] arr) {
        //第一轮比较
        int index = 0; //先拿第一个元素 跟后面的元素挨个去比
        for (int i = 1; i < arr.length; i++) {
            if (arr[index] > arr[i]) {
                swapValue(arr, index, i);
            }

        }

        //第二轮比较
        index = 1; //先拿第一个元素 跟后面的元素挨个去比
        for (int i = 1 + index; i < arr.length; i++) {
            if (arr[index] > arr[i]) {
                swapValue(arr, index, i);
            }

        }

        //第三轮
        index = 2; //先拿第一个元素 跟后面的元素挨个去比
        for (int i = 1 + index; i < arr.length; i++) {
            if (arr[index] > arr[i]) {
                swapValue(arr, index, i);
            }

        }

        //第三轮
        index = 3; //先拿第一个元素 跟后面的元素挨个去比
        for (int i = 1 + index; i < arr.length; i++) {
            if (arr[index] > arr[i]) {
                swapValue(arr, index, i);
            }

        }
    }

    //值交换的方法
    private static void swapValue(int[] arr, int j, int i) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }


}


插入排序

直接插入排序:将后面的元素,插入之前的一个有序列表,使之仍然保持有序

案例:

import java.util.Arrays;

public class ArrayDemo {
    public static void main(String[] args) {
        //直接插入排序:将后面的元素,插入之前的一个有序列表,使之仍然保持有序
        int[] arr = {2, 1, 0, 6, 9, 0, 10, 100, 20, 10, -1, 3, 6, 100, 200, 150};
        //  sortDemo1(arr);
        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0; j--) {
                if (arr[j] < arr[j - 1]) {
                    swapValue(arr, j, j - 1);
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }


    //值交换的方法
    private static void swapValue(int[] arr, int j, int i) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

    private static void sortDemo1(int[] arr) {
        //外层循环定义轮次
        for (int i = 1; i < arr.length; i++) {
            //里层就是循环让当前元素和上一个有序列表中的每个元素,比较,进行位置交换,使之仍保持有序
            int j = i;
            while (j > 0 && arr[j] < arr[j - 1]) {
                int t = arr[j];
                arr[j] = arr[j - 1];
                arr[j - 1] = t;
                j--;
            }
        }
    }
}


希尔排序

希尔排序,是对直接插入排序的一种改进,他的思想选择一个合适的增量,然后经过一轮插入排序后,就会让数组大致有序
然后不断的缩小增量,进行插入排序,直到增量为1 整个排序结束

案例:

import java.util.Arrays;
public class ArryDemo2 {
    public static void main(String[] args) {
        //希尔排序,是对直接插入排序的一种改进,他的思想选择一个合适的增量,然后经过一轮插入排序后,就会让数组大致有序
        //然后不断的缩小增量,进行插入排序,直到增量为1 整个排序结束
        int[] arr = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};

        shellSort(arr);


        //其实我们的直接插入排序,就是增量为1的希尔排序

        //int h = 1;
        //for (int i = h; i < arr.length; i++) {
        //    for (int j = i; j > h - 1; j -= h) {
        //        if (arr[j] < arr[j - h]) {
        //            swapValue(arr, j, j - h);
        //        }
        //    }
        //}
        System.out.println(Arrays.toString(arr));
    }

    private static void shellSort(int[] arr) {
        //定义增量为4
       /* int h=4;
        for (int i = h; i < arr.length; i++) {
            for (int j = i; j > h - 1; j-=h) {
                if (arr[j] < arr[j - h]) {
                    swapValue(arr, j, j - h);
                }
            }
        }

        h = 2;
        for (int i = h; i < arr.length; i++) {
            for (int j = i; j > h - 1; j -= h) {
                if (arr[j] < arr[j - h]) {
                    swapValue(arr, j, j - h);
                }
            }
        }

        h = 1;
        for (int i = h; i < arr.length; i++) {
            for (int j = i; j > h - 1; j -= h) {
                if (arr[j] < arr[j - h]) {
                    swapValue(arr, j, j - h);
                }
            }
        }*/
        //间隔选为4 不是很合理
       /* for (int h = 4; h>0; h/=2) {
            for (int i = h; i < arr.length; i++) {

                for (int j = i; j > h - 1; j -= h) {

                    if (arr[j] < arr[j - h]) {
                        swapValue(arr, j, j - h);
                    }
                }
            }
        }*/
        //间隔得选取合理 :一般第一次的增量我们选取数组长度的一半
       /* for (int h = arr.length/2; h > 0; h /= 2) {
            for (int i = h; i < arr.length; i++) {

                for (int j = i; j > h - 1; j -= h) {

                    if (arr[j] < arr[j - h]) {
                        swapValue(arr, j, j - h);
                    }
                }
            }
        }
*/
        //克努特序列
        //int h=1;
        //h=3*h+1; // 1,4,13,40,121,364


        //我要选择一个合适的增量 使用克努特序列来选

        int jianGe = 1;
        while (jianGe <= arr.length / 3) {
            jianGe = 3 * jianGe + 1;
        }

        for (int h = jianGe; h > 0; h = (h - 1) / 3) {
            for (int i = h; i < arr.length; i++) {

                for (int j = i; j > h - 1; j -= h) {

                    if (arr[j] < arr[j - h]) {
                        swapValue(arr, j, j - h);
                    }
                }
            }
        }

    }

    //值交换的方法
    private static void swapValue(int[] arr, int j, int i) {
        int t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

}


归并排序

案例:

import java.util.Arrays;
public class ArrayDemo3 {
    public static void main(String[] args) {

        int[] arr = {2, 10, 1, 0, 100, 3, 5, -1, 200, 109, 30, 1009, 109, 109, -100};

        //int[] arr={1,3,5,7,9,0,2,4,8,10};
        //归并排序
        //分
        chaiFen(arr, 0, arr.length - 1);

        //归
        // mergerSort(arr,0,(arr.length/2)-1,arr.length-1);

        System.out.println(Arrays.toString(arr));

    }

    private static void chaiFen(int[] arr, int startIndex, int endIndex) {
        //计算中间索引
        int centerIndex = (startIndex + endIndex) / 2;
        //递归来拆
        if (startIndex < endIndex) {
            //拆分左边
            chaiFen(arr, startIndex, centerIndex);
            //拆分右边
            chaiFen(arr, centerIndex + 1, endIndex);
            //归并
            mergerSort(arr, startIndex, centerIndex, endIndex);
        }
    }


    /**
     * @param arr         要归并的数组
     * @param startIndex  起始索引
     * @param centerIndex 中间索引
     * @param endIndex    结束索引
     */
    private static void mergerSort(int[] arr, int startIndex, int centerIndex, int endIndex) {
        //定义一个临时数组
        int[] tempArray = new int[endIndex - startIndex + 1];
        //定义临时数组的起始索引
        int index = 0;
        //定义左边数组的起始索引
        int i = startIndex;
        //定义右边数组的起始索引
        int j = centerIndex + 1;
        //循环比较左右两边数组的元素,往临时数组里面方法
        while (i <= centerIndex && j <= endIndex) {
            //进来比较
            if (arr[i] <= arr[j]) {
                tempArray[index] = arr[i];
                i++; //记得递增索引
            } else {
                tempArray[index] = arr[j];
                j++;//记得递增索引
            }

            index++; //临时数组的索引

        }

        //处理左边剩余元素

        while (i <= centerIndex) {
            tempArray[index] = arr[i];
            i++; //记得递增索引
            index++;
        }

        //处理右边剩余元素


        while (j <= endIndex) {
            tempArray[index] = arr[j];
            j++; //记得递增索引
            index++;
        }

        //这个时候我们的临时数组里面的元素已经排序好了

        //  System.out.println(Arrays.toString(tempArray));
        //遍历临时数组,将临时数组中的元素,放到原数组里面去
        for (int k = 0; k < tempArray.length; k++) {
            arr[k + startIndex] = tempArray[k];
        }


    }
}


快速排序

案例:

import java.util.Arrays;
public class MyTest {
    public static void main(String[] args) {
        int[] arr = {2, 1, 0, 6, 9, 0, 10, 100, 20, 10, -1, 3, 6, 100, 200, 150};
        QuickSortUtils.quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}


import java.time.Instant;
public class QuickSortUtils {

    private QuickSortUtils() {
    }

    /**
     *
     * @param arr 要排序的数组
     * @param startIndex 开始索引
     * @param endIndex 结束索引
     */
    public static void quickSort(int[] arr,int startIndex,int endIndex){
        if(startIndex<endIndex){
            //找到基准数的索引
            int index=getIndex(arr,startIndex,endIndex);
            //对左右两边进行递归调用

            quickSort(arr,startIndex,index);
            quickSort(arr,index+1,endIndex);

        }
    }

    //
    //将基准数挖出形成第一个坑。
    //由后向前找比他小的数,找到后挖出此数填到前一个坑中。
    //由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
    //再重复执行2,3两步骤。


    //挖坑填数
    private static int getIndex(int[] arr, int startIndex, int endIndex) {
        //定义三个变量
        int i=startIndex;
        int j=endIndex;
        //定义基准数
        int x=arr[i];
        while (i<j){
           //1. 由后向前找比他小的数,找到后挖出此数填到前一个坑中。
            while (i<j&&arr[j]>=x){
                j--;

            }
            //填坑
            if(i<j){
                arr[i]=arr[j];
                i++;//顺便让i增一下
            }
            //2,由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中
            while (i<j&&arr[i]<x){

                i++;
            }

            //填坑
            if (i < j) {
                arr[j] = arr[i];
                j--; //顺便让j减一下
            }


        }
        //以上循环完毕之后,将基准数填到最后一个坑里面去
        arr[i]=x;

        return i;
    }
}


基数排序
案例:

import java.util.Arrays;
public class 基数排序算法 {
    public static void main(String[] args) {
        int[] arr = {1, 9, 8, 12, 23, 28, 32, 42, 102, 100, 259};
        sortArray(arr);
        System.out.println(Arrays.toString(arr));

    }

    private static void sortArray(int[] arr) {
        //定义一个二维数组
        int[][] tempArr = new int[10][arr.length];//里面的一维数组的长度最大就和待排序的数组长度一样
        //定义一个统计的一维数组,可以统计二维数组每个桶中放了多少数字
        int[] counts = new int[10];//长度和二维数组长度保持一样
        //获取数组中最大的数
        int max = getMax(arr);
        //计算数组中最大的数的有几位,这就是我们需要比较的轮次
        int len = String.valueOf(max).length();
        for (int i = 0, n = 1; i < len; i++, n *= 10) {
            for (int j = 0; j < arr.length; j++) {
                //获取每个位上的数字
                int ys = arr[j] / n % 10;
                //我们找一个二维数组,数组中放10个桶,这个桶就是一位数组
               // counts[ys]++ 意思是,二维数组的桶中放一个数字,那么统计数组对于的位置就统计一下
                tempArr[ys][counts[ys]++] = arr[j];
            }
            //我们遍历统计数组,取出二维数组中的元素,放回原数组
            int index = 0;
            for (int k = 0; k < counts.length; k++) {
                if (counts[k] != 0) {
                    for (int h = 0; h < counts[k]; h++) {
                        arr[index] = tempArr[k][h];
                        index++;
                    }
                    //情况一轮过后统计的个数
                    counts[k] = 0;
                }
            }
        }


    }

    private static int getMax(int[] arr) {
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }

        return max;
    }
}


import java.util.Arrays;
import java.util.SortedMap;
import static java.util.Arrays.sort;
public class ArrayDemo2 {
    public static void main(String[] args) {
        //基数排序
        int[] arr = {21,31,444,23,33,47,1000,900,124,987,0,100,0};
        //int max=getMax(arr);
        sortArr(arr);
        System.out.println(Arrays.toString(arr));
    }

    private static void sortArr(int[] arr) {
        //最大数有几位,我们就排几轮
        int max = getMax(arr);
        int len = String.valueOf(max).length();
        //len=2;
        //定义一个二维数组,长度为10
        int[][] tempArr = new int[10][arr.length];
        //再定义一个数组,长度和二维数组的长度一样,用于记录二维数组中的每一个桶位存了几个数字
        int[] counts = new int[10];

        for (int i = 0, n = 1; i < len; i++, n *= 10) {
            //循环遍历,取每个位上的数字
            for (int j = 0; j < arr.length; j++) {
                //取每个位上的数字
                int ys = arr[j] / n % 10;
                //int count=counts[ys];
                tempArr[ys][counts[ys]]=arr[j];
                counts[ys]++;
               // count++;//二维数组中的一维数组放了要一个数,就在统计数组对应的位置统计一下
               // counts[ys] = count; //将累加后的值,赋值给统计数组
            }
            //取出每个桶中的元素,放入原来的数组
            int index=0;
            for (int k = 0; k < counts.length; k++) {
               //取出统计数组在每个位置上统计的个数
                if(counts[k]!=0){
                    for (int h = 0; h < counts[k]; h++) {
                        arr[index]=tempArr[k][h];
                        index++;
                    }
                    counts[k] = 0; //一趟完成后,把统计的个数清0
                }

            }
        }
        //for (int i = 0; i < tempArr.length; i++) {
        //    System.out.println(Arrays.toString(tempArr[i]));
        //}


    }

    private static int getMax(int[] arr) {
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值