快速排序

      快速排序是一种常见的排序算法,大多数情况下快速排序都是最快的。快速排序本质上是将一个数组划分一个子数组(关于划分前面已经说过),递归调用自身为每一个子数组进行快速排序。

       快速排序的过程:以数组为例,针对数组进行排序。

1 把数组或者子数组划分为左边(比关键字小的)一组和右边比关键字大的一组。

2 调用自身对左边一组进行排序。

3 再次调用自身对右边的一组进行排序。

4 不断递归循环以上步骤,子数组长度不断缩短。最终通过不断划分数组的方式直到限制一个数据项时返回,这也是递归的基值条件。

      快速排序针对每个子数组使用的是关键字排序。这里的关键字可以使用每个子数组的最右端数据项。在划分的基础上需要添加一个步骤就是在交换双边数据时还需要交换关键字与数据划分位置。以下图表示这个过程:

这里写图片描述

      采用递归实现快速排序,下图表示以上几个步骤:

这里写图片描述

      第一次进行划分,划分两个子数组,通过交换数据项和关键字,可以得到下图:

这里写图片描述

      初次以数组最右端为关键字(这里是数据项18),以18为划分项,左右两边进行子数组递归再进行划分和交换操作。

这里写图片描述

      接下来就是独自对两个子数组进行递归划分交换即可;

这里写图片描述

      继续递归,条件判断,不断划分子数组,不断交换关键字。

这里写图片描述

      关键字12左端已经是有序不需要交换,右端已经是一个数据项此次递归return,结合其他子数组的划分情况。此时综合就是一个有序数组。

这里写图片描述

以下是快速排序的递归代码:

//采用递归实现快速排序算法
    //在划分的基础上实现数据的交换
    //每次递归都能实现对一个数据项的交换
    public void quickSort(int left,int right)
    {
        if(right-left<=0)
            return;
        else
        {
            int temp=array[right];
            int partion=divide(left,right,temp);
            //分治思想 对左边和右边的数据项都进行排序
            //由于partion位置明确 
            //只需要对partion左边和右边进行排序
            quickSort(left, partion-1);
            quickSort(partion+1, right);
        }
    }

      以下是划分算法,相比较之前的划分算法这里的关键字是需要指定的,这里以每个子数组的最右端数据项为关键字。

//划分算法 
    public int divide(int left,int right,int actionNum)
    {

         int leftPtr=left-1;
         int rightPrt=right;
         //不断进行划分 当left指针right指针相遇时跳出循环
         while(true)
         {
             //循环从左向右进行查找
             //注意边界监测
             while(array[++leftPtr]<actionNum)
             {
                 ;//查找的数据项都比actionNum都要小 可以什么都不做
             }
             while(rightPrt>0&&array[--rightPrt]>actionNum)
             {
                 ;//查找的数据项都actionNum多都要大 可以什么都不做
             }
             //判读退出循环条件
            if(leftPtr>=rightPrt)
            {
                break;

            }
             //当以上有两种情况发生时 进行交换数据项
            else
            {
                swap(leftPtr,rightPrt);
            }   
         }
         //交换最右端数据与leftPtr处数据
         swap(leftPtr,right);
         return leftPtr;

       数据交换,一个划分过程中出现的左右子数组数据交换,另外一个是关键字的交换。

public void swap(int left,int right)
    {
        int temp=0;
        temp=array[left];
        array[left]=array[right];
        array[right]=temp;
    }
    public void showArray()
    {
        //System.out.println("排序之后:");
        for(int i=0;i<array.length;i++)
        {
            System.out.print(array[i]+" ");
        }
        System.out.println("");
    }

随机数组的创建

private int[] array=null;
    //获取数组 随机数产生数组
    public QuickSort(int n)
    {
        array=new int[n];
        for(int i=0;i<n;i++)
        {
            int a=(int)(Math.random()*100);
            array[i]=a;
        }
        System.out.println("排序之前:");
        showArray();
    }
    //封装快速排序算法
    public void quick()
    {
        quickSort(0,array.length-1);
    }

测试与结果:

QuickSort quickDemo=new QuickSort(18);
        quickDemo.quick();
        System.out.println("排序之后");
        quickDemo.showArray();
排序之前:
74 92 61 12 36 33 38 31 25 69 42 76 81 95 37 67 80 41 
排序之后
12 25 31 33 36 37 38 41 42 61 67 69 74 76 80 81 92 95 

快速排序的效率

      快速排序的时间复杂度为O(N*log(N))。快速排序采用的是分治思想,快速排序比一般排序要快,效率较高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值