快速排序-[Java实现]

1 篇文章 0 订阅

快速排序又被称为分割交换排序,是目前公认最佳的排序方法。它的原理和冒泡排序一样都是用交换的方式,不过它会现在数据中找到一个虚拟的中间值作为基准数,把小于这个基准数的数据放到它的左边,大于这个基准数的数据放到它的右边,再以递归的方式处理这个基准数左右两边的数据,直到完成为止。

假设我们有一组数56,18,6,3,97,66,8,26,88,30,99,93

第一轮,我们将56视为基准数

将大于它的数据放到它的右边,小于它的数据放到它的左边

再将最左侧的8视为基准数,将大于它的数据放到它的右边,小于它的数据放到它的左边

再选定6为基准数

左侧只剩一个3,不用排它也已经归为

我们再来排8的右侧,以18为基准数

这样,18就归归位了,它的左侧没有其它数字,那么我们再看它的右边,以30为基准数

排序过后左边就完成了

右边同理

不断的把左侧第一个数据当作基准数,一个一个地归为

通过上述图解,我们应该理解了快速排序的基本思路,这样我们就可以写出一个大致的框架:

//将索引left到right区间的下标元素进行快速排序
 public static void quickSort(int[] arr,int left,int right) {
      if(left>=right)return;//如果left大于等于right,方法结束
      int p = arr[left];//设置最左边的元素为基准点
      
      
     ··· ···//把序列当中比p大的放到右边,比p小的
      ··· ···//放到左边,p放置在下标为i的位置
         
     
      quickSort(arr,left,i-1);//对序列中i左边的元素实施快速排序
      quickSort(arr,i+1,right);//对序列中i右边的元素实施快速排序
  }    

大致框架写好了,我们所要研究的就是中间的代码,怎样做到基准数的左侧都小于它,右侧都大于它呢?我们先用图片的方式来看一下:

 首先我们设置两个循环变量,i 指向最左边,j 指向最右边,变量 p 的值为最左边的元素的值

先让 j 向左移动,一直到碰到一个比 p 的值小的元素

再让 i 向右移动,一直到碰到一个比 p 的值大的元素

这两个元素交换一下位置

接着我们重复之前的行为,让 j 继续向左移动,一直到它再次碰到一个比 p 值小的元素

然后,i 再向右移动,一直到它再次碰到一个比 p 值大的元素

找到之后,再交换一下

接着我们继续让 j 去找比p小的值,让 i 去找比p大的值

 

 当我们发现,i 等于 j 时,交换 p 和 j 的元素,

 

 

这样,我们的第一轮排序就完成了

我们通过代码来实现一下这一轮所进行的行为:

//设置最左边的元素为基准点
int p = arr[left];
        
//把要排序的序列中比p大的放到右边,比p小的放到左边,p的下标位置为i
int i = left,j=right;
while(i!=j) {
    //j向左移动,找到一个比p小的元素
    while(arr[j]>=p && i<j) {
        j--;
    }
    //i向右移动,找到一个比p大的元素
    while(arr[i]<=p && i<j) {
        i++;
    }
    //i和j交换,如果i>j则不交换
    if(i<j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}
//将j找到的最后一个比p小的值与基准值交换
arr[left] = arr[i];
arr[i] = p;

我们再将这段代码套入之前的框架

public static void quickSort(int[] arr,int left,int right) {
        //如果left大于等于right,则需要排序的部分至多只有一个元素,方法结束
        if(left>=right) {
            return;
        }
        //设置最左边的元素为基准点
        int p = arr[left];
        
        //把要排序的序列中比p大的放到右边,比p小的放到左边,p的下标位置为i
        int i = left,j=right;
        while(i!=j) {
            //j向左移动,找到一个比p小的元素
            while(arr[j]>=p && i<j) {
                j--;
            }
            //i向右移动,找到一个比p大的元素
            while(arr[i]<=p && i<j) {
                i++;
            }
            //i和j交换,如果i等于j则不用再交换
            if(i<j) {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        //将j找到的最后一个比p小的值与基准值交换
        arr[left] = arr[i];
        arr[i] = p;
        
        //对序列中,j左边的元素实施快速排序
        quickSort(arr,left,i-1);
        //对序列中,j右边的元素实施快速排序
        quickSort(arr,i+1,right);35     }

这样,我们的快速排序算法就写完啦

我们将举例的一组数据输入,来测试一下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值