Java快速排序与归并排序及基数排序图解示例

 更新时间:2022年09月24日 14:33:26   作者:小黎的培培笔录  
快速排序是基于二分的思想,对冒泡排序的一种改进。主要思想是确立一个基数,将小于基数的数放到基数左边,大于基数的数字放到基数的右边,然后在对这两部分进一步排序,从而实现对数组的排序

一、快速排序

1、基本介绍

以上面的数组为例分析快速排序。

首先要传入三个值,数组arr[ ] ,最左边下标left ,最右边下标 right。然后将根据左右的下标值计算出中间值mid。

我们要做的就是将左边的值大于mid的放到右边,将右边小于mid的值放到左边。

左右两边分别单独循环,左边找到比mid大的数,右边找到比mid小的数。

两边分别找到符合条件的数后,进行交换。

然后继续比较并交换,此刻 l 和 mid 都指向3,r 指向 5 。

这时需要进行判断,如果arr[l] 等于mid 则 r--,如果arr[r] 等于mid则 l++ 。此时又进行判断arr[l] 是否等于arr[r],等于则退出。第一轮就结束了。

第一次完以后,我们使用递归,递归会重复上面的操作,从而完成排序。

2、代码实现

//参数传入数组arr , 最左边的下标left,最右边的下标 right
public static void quickSort(int[] arr , int left , int right){
        //分别用临时变量代替
        int l = left;
        int r = right;
        //中间的下标
        int middle = arr[(left + right) / 2];
        //临时变量,用于交换数据
        int temp = 0;
        //进行循环,只要右边的下标 l 小于 左边的下标 r 就进行循环
        while (l < r){
            //左边l 到 中间middle 单独循环,找到比middle大的值
            while (arr[l] < middle){
                l += 1;
            }
            //中间middle 到 右边 r 单独循环,找到比middle小的值
            while (arr[r] > middle){
                r -= 1;
            }
            //退出循环,表示找到,不过先判断 l 是否大于等于 r 
            //满足就可以退出循环,不需要执行下面的代码了
            if(l >= r){
                break;
            }
            //找到的数据进行交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;
            //此时进行判断,如果arr[l] 等于middle  则 r--
            if(arr[l] == middle){
                r -= 1;
            }
            //如果  arr[r] 等于middle 则 l++
            if(arr[r] == middle){
                l += 1;
            }
        }
        //退出循环,l 会等于 r,此时要将两者移位,l进行加一,r进行减一
        if(l == r){
            l += 1;
            r -= 1;
        }
        //第一轮完成后进行递归
        //重复上面的方法,向左递归
        if(left < r){
            //r 继续往前移的,所以左下标为left ,右下标为 r
            quickSort(arr, left , r);
        }
        //重复上面的操作,向右递归
        if(right > l){
            //l 继续往后移的,所以左下标为 l ,右下标为 right
            quickSort(arr, l , right);
        }
    }

二、归并排序

1、基本介绍

2、代码实现

▶ 首先实现合并

public static void merger(int[] arr , int left ,int mid , int right , int[] temp){
        int i = left;
        int j = mid + 1;
        int t = 0;//数组temp的下标
        //将arr数组按顺序放入temp 数组
        while (i <= mid  && j <= right){
            //从中间分隔开,左边和右边相互比较
            //如果左边更小,先放入temp数组,否则右边先放入
            if(arr[i] < arr[j]){
                temp[t] = arr[i];
                i++;
                t++;
            }else {
                temp[t] = arr[j];
                j++;
                t++;
            }
        }
        //有可能有一边还没放完,于是继续循环放放入
        //左边没放完
        while (i <= mid){
            temp[t] = arr[i];
            t++;
            i++;
        }
        //右边没放完
        while (j <= right){
            temp[t] = arr[j];
            j++;
            t++;
        }
        //将temp中数据拷入到arr
        t = 0;
        int leftind = left;
        //第一次(leftind,right)是(0,1)(2,3)(4,5)(6,7)
        //第二次(leftind,right)是(0,3)(4,7)
        //第三次(leftind,right)是(0,7)
        while (leftind <= right){
            arr[leftind] = temp[t];
            t++;
            leftind++;
        }
    }

▶ 分隔和合并进行递归

public static void mergerSort(int[] arr, int left,int right, int[] temp){
        //判断
        if (left < right){
            //求出中间值
            int mid = (left + right) / 2;
            //调用自己,向左递归
            mergerSort(arr, left, mid , temp);
            //调用自己,向右递归
            mergerSort(arr , mid + 1, right, temp);
            //调用merger进行合并
            merger(arr, left , mid, right, temp);
        }
    }

三、基数排序

1、基本介绍

首先我们需要10个数组,分别对应10个桶,每个桶有对应的下标。

然后按每个数的个位数大小放入对应的桶中,放好后,按桶的顺序依次取出。

第二次是看每个数的十位,不及十位的就当做0,依旧是依次放入对应的桶中,并按顺序取出。

第三次是看每个数的百位,重复上面的操作,最后得到的就是有序的数组。

2、代码实现

public static void cardinalitySort(int[] arr){
        //首先找到数组中最大数的位数
        int max = arr[0];
        for(int i = 1; i < arr.length - 1; i++ ){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        int maxLength = (max + "").length();
        //定义10个桶,每个桶大小为数组大小
        int[][] bucket = new int[10][arr.length];
        //定义一个数组来表示每个桶存放的数据
        int[] bucketcount = new int[10];
        //n是用来进行位数处理的
        for(int i = 1, n = 1; i <= maxLength ; i++,n *= 10){
            for(int j = 0; j < arr.length ; j++){
                //对每位数进行位处理,并放入桶中
                int elentData = arr[j] / n % 10;
                /*    
                  放对应的桶中,
                  bucketcount[elentData]表示对应的桶的数据,
                  假如第一个数为579,要放入bucketcount[9](第九个桶)的第一个位置,
                  默认初始化为0,所以第一个数放入的位置是bucketcount[9] = 0
                */
                bucket[elentData][bucketcount[elentData]] = arr[j];
                //第一个数放完后,这个桶中数据进行++,
                //下次再放入这个桶时,bucketcount[9] = 1
                bucketcount[elentData]++;
            }
            int index = 0;
            //遍历每一个桶
            for(int k = 0; k < bucketcount.length; k++){
                //第一次默认为bucketcount[k] = 0
                //所以如果第一个数为零,就说明这个桶为空
                if(bucketcount[k] != 0){
                    //有数据,则桶bucketcount[k]就会有对应数据多少的大小,进行遍历
                    for(int l = 0; l < bucketcount[k] ; l++){
                        //放入原来的数组
                        arr[index++] = bucket[k][l];
                    }
                }
                //桶中的数放回原数组放完后,进行置空
                bucketcount[k] = 0;
            }
        }
    }

到此这篇关于Java快速排序与归并排序及基数排序图解示例的文章就介绍到这了,更多相关Java快速排序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文盘点五种最常用的Java加密算法

    一文盘点五种最常用的Java加密算法

    大家平时的工作中,可能也在很多地方用到了加密、解密,比如:支付功能等,所以本文为大家盘点了Java中五个常用的加密算法,希望对大家有所帮助
    2023-06-06
  • Java HashSet的Removals()方法注意事项

    Java HashSet的Removals()方法注意事项

    这篇文章主要介绍了Java HashSet的Removals()方法注意事项,文章围绕制主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-06-06
  • 轻松掌握Java代理模式

    轻松掌握Java代理模式

    这篇文章主要帮助大家轻松掌握Java代理模式,什么是静态代理?感兴趣的小伙伴们可以参考一下
    2016-09-09
  • Springboot+netty实现Web聊天室

    Springboot+netty实现Web聊天室

    这篇文章主要介绍了利用springboot+netty实现一个简单Web聊天室,文中有非常详细的代码示例,对正在学习Java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-12-12
  • java结合HADOOP集群文件上传下载

    java结合HADOOP集群文件上传下载

    这篇文章主要介绍了java结合HADOOP集群文件上传下载的方法和示例,非常的实用,这里推荐给大家,希望大家能够喜欢。
    2015-03-03
  • Java如何实现简单后台访问并获取IP

    Java如何实现简单后台访问并获取IP

    这篇文章主要介绍了Java如何实现简单后台访问并获取IP,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • 关于SpringBoot中的XA事务详解

    关于SpringBoot中的XA事务详解

    这篇文章主要介绍了关于SpringBoot中的XA事务详解,事务管理可以确保数据的一致性和完整性,同时也可以避免数据丢失和冲突等问题。在分布式环境中,XA 事务是一种常用的事务管理方式,需要的朋友可以参考下
    2023-07-07
  • 详解Spring AOP

    详解Spring AOP

    本文非常详细讲解了Spring AOP,本篇文章通过大量的代码,讲解了Spring AOP的使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 基于mybatis-plus timestamp返回为null问题的排除

    基于mybatis-plus timestamp返回为null问题的排除

    这篇文章主要介绍了mybatis-plus timestamp返回为null问题的排除,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • java如何动态的处理接口的返回数据

    java如何动态的处理接口的返回数据

    本文主要介绍了java如何动态的处理接口的返回数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01

最新评论