常见排序算法——冒泡排序,插入排序,希尔排序,归并排序,选择排序,快速排序

本文主要收集整理了一下自己学习的思路,借鉴了一些优秀博主对其的理解。

1.冒泡排序(Bubble Sort)

思路:

假设我们从小到大排序:

它重复地走访要排序的元素列,依次比较两个相邻的元素,如果左边大于右边,就将左右数进行交换,这样,我们每次都能找到一个最大的值,并放到数组最右边。

代码:

    public static void bubblingSort(int[] array){
        int time = array.length-1;//初始化要交换的次数
        int a  = 0;//临时变量,用于交换
        for(int i = 0;i<array.length-1;i++){
            int count = 0;//变量用于记录交换次数
            for(int j = 0;j<time;j++){
//                判断大小,大就交换
                if(array[j]>array[j+1]){
                     a = array[j];
                    array[j] = array[j+1];
                    array[j+1] = a;
                    count++;
                }
            }
            if(count==0){//如果一次循环中没完成一次交换,那么直接退出,无需再重复做无用循环
                break;
            }
            time--;
        }
        for(int i = 0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
    }

2.插入排序(InsertionSort)

思路:

如果:arr[index]>arr[index+1],就让arr[index+1]=arr[index] 然后和下一个比

这样一直比,直到arr[index]<arr[index+1],再插入即可;

代码:

 public static void insertSort(int[] array){
        for(int i = 1;i<array.length;i++){
            int insertValue = array[i];//每次那一个值来插入
            int index = i-1;//表示最后一个元素的下标
            while(index>=0&&insertValue<array[index]){//当插入的值小于最后一个元素
                array[index+1] = array[index];//将最后一个的值后移一位,为后续插入腾位置
                index--;//最后一个比不过就退一个比,直至比到满足条件
            }
//            退出循环就是满足条件
            if(index+1 !=i) {//如果现在插入的位置就是它本来的位置,你那么就不用插入
                array[index + 1] = insertValue;
            }
        }
//        打印结果
        for(int i = 0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
    }

3.希尔排序

思路:希尔排序就是缩小增量的插入排序

例:

初始增量第一趟 gap = length/2 = 4

 第二趟,增量缩小为 2

第三趟,增量缩小为 1,得到最终排序结果

代码:

   public static String shell2(int [] sort){

        for( int len = sort.length/2;len>0;len/=2) {
//            这里是计算出每次要操作的次数
            for(int i = len;i<sort.length;i++){
                int j =i;
//                记录当前操作值
                int temp = sort[j];
//                此时前一个数小于隔自己步数值的数
                if(sort[j] <sort[j-len]){
                    while (j-len>=0&& temp<sort[j-len]){
                        sort[j] = sort[j-len];
                        j-=len;
                    }
                    sort[j] = temp;
                }
            }
        }
        return Arrays.toString(sort);
    }

4.归并排序

思路:归并排序采用的是分治的思想

归并排序,先将待排序的数组不断拆分,直到拆分到区间里只剩下一个元素的时候。不能再拆分的时候。这个时候我们再想办法合并两个有序的数组,得到长度更长的有序数组。当前合并好的有序数组为下一轮得到更长的有序数组做好了准备。一层一层的合并回去,直到整个数组有序。

 

 如何进行合并?

由于数组分到最后只有一个,那么相对于他的父数据,中轴左右是有序的。

就比如:

那么我们只需要将子数组的左右依次遍历,谁小就将其保存,这样遍历完子数组,整合起来的父数组就是有序的

代码:

 /**
     * 递归函数对nums[left...right]进行归并排序
     * @param nums 原数组
     * @param left 左边的索引
     * @param right 右边记录索引位置
     * @param temp
     */
    private static void mergeSort2(int[] nums, int left, int right, int[] temp) {
        if (left == right){//当拆分到数组当中只要一个值的时候,结束递归
            return;
        }
        int mid = (left+right)/2;   //找到下次要拆分的中间值
        mergeSort2(nums,left,mid,temp);//记录树左边的
        mergeSort2(nums,mid+1,right,temp);//记录树右边的

        //合并两个区间
        for (int i = left; i <= right; i++) {
            temp[i] = nums[i];
        //temp就是辅助列表,新列表的需要排序的值就是从辅助列表中拿到的
        }
        int i = left;       //给辅助数组里面的值标点
        int j = mid +1;
        for (int k = left; k <= right ; k++) {//k 就为当前要插入的位置
            if (i == mid + 1){//左边全满了
                nums[k] = temp[j];
                j++;
            }else if (j == right+1){//右边全满了
                nums[k] = temp[i];
                i++;
            }
            else if (temp[i] <= temp[j]){
                nums[k] = temp[i];
                i++;
            }else {
                nums[k] = temp[j];
                j++;
            }
        }
    }

5.选择排序:

思路:依次找最小值

代码:

 public static void selectSort(int[] array){
        for(int i = 0;i<array.length-1;i++){
            //        假定最小数
            int index = i;
            int min = array[i];
            for(int j = i+1;j<array.length;j++){//找到最小值
                if(min>array[j]){//如果假定最小值大于之后的一个数,重置最小数
                    min = array[j];
                    index = j;
                }
            }
            if(index!=i){//判断现在交换完最后最小数是不是之前的那个最小数
                array[index] = array[i];
                array[i] = min;
            }
        }

6.快速排序

思路:

每次递归让其基准数左边全部小于基准数,其右边大于基准数。

这个博主写的快速排序通俗易懂。

https://blog.csdn.net/weixin_45970271/article/details/124460317

代码:

 public static void sort(int[] arrays, int left, int right) {
        if(left > right) {
            return;
        }
        int l = left;
        int r = right;
        int pivot = arrays[left];
        int temp = 0;
        while(l < r) {
            while(pivot <= arrays[r] && l < r) {
                r--;
            }
            while(pivot >= arrays[l] && l < r) {
                l++;
            }
            if(l <= r) {
                temp = arrays[r];
                arrays[r] = arrays[l];
                arrays[l] = temp;
            }
        }
        arrays[left] = arrays[l];
        arrays[l] = pivot;
        sort(arrays, left, l - 1);
        sort(arrays, l + 1, right);
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值