排序算法——快速排序

今天我们来说一说快速排序吧!


其实快速排序跟冒泡排序的原理差不多

快速排序算法流过多次比较和交换来变现挣序,其排序流程如下:

(1)首光设定一个分界值,通过该分界值将数组分成左右两部分。

(2)将大于等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时左边部分中各元素都小于等于分界值,而右边部分中各元素都大于等于分界值。

(3)然后,上边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分第值,将该部分数据分成左右两部分,同样将左边放置最小值,右边放置最大值。右侧的数组数据也可以做类似处理。

(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分挂好序后,再递归排好右侧部分的顺序。当左、右两部分各数据排序完成后,整个数组的排序也就完成了。

为了更好地理解快速排序算法的执行过程,下面举一个实际数据的例子来一步一步地执行快速排序算法,下面所示。8个整型数据 69、62、89、37、97、17、28、49 是一组无序的数据。对其执行快速排序过程:
(1)首先选取一个分界值,这里选择第一个数据69作为分界值。在变量left中保存数组的最小序号0,在变量right中保存数组的最大序号7,在变量base中保存分界值69;
(2)从数组右侧开始,逐个取出数据与分界值69比较,直到找到比base 小的数据为止,数组最右侧的元素A[right]的值49比base变量中保存的值69小;
(3)将右侧比基准 base小的数(数组元素A[right]中的数)保存到A[left](A[0])元素中。
(4)接下来,从数组左侧开始,逐个取出元素与分界值69比较,直到找到比分界值69大的数据为止。数组最左侧的元素A[left](即 A[0])的值为49,比 base的值小,将left自增1(值为1)。再取 A(left](A[1)的值 62与 base 的值69 比较,62小于69,继续将 left 自增1(值为2),再取A[left](A[2])的值89与base 比较,89大于69,结束查找。
(5)将左侧比分界值69大的数(数组元素A[2])保存到A[right](A[7])元素中。
(6)将分界值69中的值保存到A[left](A[2])中,最后得到的结果如下:

69(left) 62 89 37 97 17 28 49(right) 69(base)
49 62 69 37 97 17 28 89(right) 69(base)

经过这一次分割,base 数据左侧的数(即left 所指向的数据)比分界值69小,而 base数据右侧的数据比base大。
羊的排序。
(7)接下来,通过递归调用,将lef 左侧的数据进行同样的排序,再将 Ieft 右侧的数据进行同样的排序。

经过上述递归调用,最终可完成数据的排序操作。

快速排序算法的代码:

public static void quickSort(int[] arr,int left,int right){
        int l=left;//左下标
        int r=right;//右下标
        //pivot 中轴值
        int pivot=arr[(left+right)/2];
        int temp=0;//临时变量,交换时使用
        //while循环的目的是让比pivot小的值放到左边
        //比pivot大的放在右边
        while (l<r){
            //在pivot左边一直找,直到找到大于等于pivot的值,才退出
            while (arr[l]<pivot){
                l+=1;
            }//在pivot右边一直找,直到找到小于等于pivot的值,才退出
            while (arr[r]>pivot){
                r-=1;
            }
            //如果l>=r成立,说明pivot的左右的值,已经按照左边小于等于pivot的值,而右边全部是大于等于pivot的值
            if(l>=r){
               break;
            }
            //交换
            temp=arr[l];
            arr[l]=arr[r];
            arr[r]=temp;

            //如果交换完后,发现arr[l]==pivot值相等 r--,前移
            if(arr[l]==pivot){
                r-=1;
            }
            //如果交换完后,发现arr[r]==pivot值相等 l++,后移
            if(arr[r]==pivot){
                l+=1;
            }
        }

        //如果l==r,必须l++,r--.否则表现为栈溢出
        if(l==r){
            l+=1;
            r-=1;
        }
        //向左递归
        if(left<r){
            quickSort(arr,left,r);
        }

        //向右递归
        if(right>l){
            quickSort(arr,l,right);
        }
    }

结果为:
在这里插入图片描述

看一看给80000个数据排序的效率如何?

//创建要给800000个数据的数组
        int[] arr=new int[800000];
        for(int i=0;i<800000;i++){
            arr[i]=(int)(Math.random()*8000000);//生成一个[0,8000000)数
        }

        Date date1=new Date();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str=simpleDateFormat.format(date1);
        System.out.println("排序前的时间:"+date1Str);

        quickSort(arr,0,arr.length-1);

        Date date2=new Date();
        String date2Str=simpleDateFormat.format(date2);
        System.out.println("排序后的时间:"+date2Str);



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

结果展示:
在这里插入图片描述
基本上都不用花时间,一下子就排出来了

=============================================================
完整代码:

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * @Author DreamYee
 * @Create 2019/10/27  14:18
 */
public class QuickSort {
    public static void main(String[] args) {
        //int[] arr={-9,78,0,23,-567,70,900,4561};

        /*
        int[] arr={ 69,62,89,37,97,17,28,49};
        System.out.println("排序前的数组:"+"\n"+Arrays.toString(arr));
        System.out.println("排序后的数组:");
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
        */


        //创建要给800000个数据的数组
        int[] arr=new int[800000];
        for(int i=0;i<800000;i++){
            arr[i]=(int)(Math.random()*8000000);//生成一个[0,8000000)数
        }

        Date date1=new Date();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1Str=simpleDateFormat.format(date1);
        System.out.println("排序前的时间:"+date1Str);

        quickSort(arr,0,arr.length-1);

        Date date2=new Date();
        String date2Str=simpleDateFormat.format(date2);
        System.out.println("排序后的时间:"+date2Str);



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

    }

    public static void quickSort(int[] arr,int left,int right){
        int l=left;//左下标
        int r=right;//右下标
        //pivot 中轴值
        int pivot=arr[(left+right)/2];
        int temp=0;//临时变量,交换时使用
        //while循环的目的是让比pivot小的值放到左边
        //比pivot大的放在右边
        while (l<r){
            //在pivot左边一直找,直到找到大于等于pivot的值,才退出
            while (arr[l]<pivot){
                l+=1;
            }//在pivot右边一直找,直到找到小于等于pivot的值,才退出
            while (arr[r]>pivot){
                r-=1;
            }
            //如果l>=r成立,说明pivot的左右的值,已经按照左边小于等于pivot的值,而右边全部是大于等于pivot的值
            if(l>=r){
               break;
            }
            //交换
            temp=arr[l];
            arr[l]=arr[r];
            arr[r]=temp;

            //如果交换完后,发现arr[l]==pivot值相等 r--,前移
            if(arr[l]==pivot){
                r-=1;
            }
            //如果交换完后,发现arr[r]==pivot值相等 l++,后移
            if(arr[r]==pivot){
                l+=1;
            }
        }

        //如果l==r,必须l++,r--.否则表现为栈溢出
        if(l==r){
            l+=1;
            r-=1;
        }
        //向左递归
        if(left<r){
            quickSort(arr,left,r);
        }

        //向右递归
        if(right>l){
            quickSort(arr,l,right);
        }
    }
}

好了,今天就说到这里吧
哈哈哈,天天好心情!^ _ ^

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值