前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >快速排序算法

快速排序算法

作者头像
Vincent-yuan
发布2020-05-08 15:20:49
5150
发布2020-05-08 15:20:49
举报
文章被收录于专栏:Vincent-yuanVincent-yuan

快速排序算法本质上是通过把一个数组划分为两个子数组,然后递归的调用自身为每一个子数组进行快速排序来实现的。

这里首先讲递归的快速排序算法。

1.递归的排序算法

代码语言:javascript
复制
    public void recQuickSort(int left, int right){
        if(right-left<=0){  //如果right-left<=0,表示已经排好序了
            return;
        }else{
            long pivot = theArray[right];
            
            int partition = partitionIt(left, right, pivot);
            recQuickSort(left, partition-1);
            recQuickSort(partition+1, right);
        }
    }

正如上面的代码,有三个基本步骤:

  1. 把数组或子数组划分成左边(较小的关键字)的一组和右边(较大的关键字)的一组。
  2. 调用自身对左边的一组进行排序。
  3. 再次调用自身对右边的一组进行排序。

这个递归的基值(终止)条件:检查数组是否只包含一个数据项,如果是,就定义数组已经有序,方法返回。

那么如何检查数组只包含一个数据项呢?即right - left <= 0;

patitionIt()方法应该使用什么样的枢纽呢?

  • 应该选择具体的一个数据项的关键字的值作为枢纽;称这个数据项为pivot(枢纽).
  • 可以选择任意一个数据项作为枢纽。为了简便我们总选择待划分的子数组最右端的数据项作为枢纽。
  • 划分完成之后,如果枢纽被插入到左右子数组之间的分界处,那么枢纽就落在排序之后的最终位置上了。

递归排序算法思想简图

递归排序实际数据效果图

这里贴出递归方式快速排序代码实现

代码语言:javascript
复制
package com.vincent.suanfa;

public class quickSort1 {

    public static void main(String[] args){
        int maxSize = 16;
        ArrayIns arr;
        arr = new ArrayIns(maxSize);
        //填充数组
        for(int j=0; j < maxSize; j++){
            long n = (int)(java.lang.Math.random()*99); //生成随机数
            arr.insert(n);
        }
        arr.display();
        arr.quickSort();
        arr.display();
    }
}

class ArrayIns{
    private long[] theArray; //数组
    private int nElems; //标识数组最大下标(即长度-1)
    
    //构造函数
    public ArrayIns(int max){
        theArray = new long[max];
        nElems = 0;
    }
    
    //把数据插入数组
    public void insert(long value){
        theArray[nElems] = value;
        nElems++;
    }
    
    //打印数组
    public void display(){
        System.out.print("A=");
        for(int j=0; j<nElems; j++){
            System.out.print(theArray[j] + " ");
        }
        System.out.println("");
    }
    
    public void quickSort(){
        recQuickSort(0,nElems-1);
    }
    
    public void recQuickSort(int left, int right){
        if(right-left<=0){  //如果right-left<=0,表示已经排好序了
            return;
        }else{
            long pivot = theArray[right];
            
            int partition = partitionIt(left, right, pivot);
            recQuickSort(left, partition-1);
            recQuickSort(partition+1, right);
        }
    }
    
    //分区函数
    public int partitionIt(int left, int right, long pivot)
    {
        int leftPtr = left-1;
        int rightPtr = right;
        while(true)
        {
            //leftPtr表示数组下标为leftPtr时,其值小于pivot;目的是找到下标大于等于pivot的下标;即分出pivot左边的部分
            while( theArray[++leftPtr] < pivot);  
            
            //rightPtr表示数组下标为rightPtr时,其值大于pivot;目的是找到下标小于等于pivot的下标;即分出pivot右边的部分
            while( rightPtr>0 && theArray[--rightPtr] > pivot);  
            
            if(leftPtr >= rightPtr)        //表示小于pivot的下标和大于pivot的下标交叉了,分区结束
                break;                    
            else
                swap(leftPtr, rightPtr);  //把数据项按枢纽分成两组
        }
        swap(leftPtr, right);
        System.out.println("分区:");
        display();
        System.out.println("分区下标: "+leftPtr);
        return leftPtr;
    }
    //交换数据
    public void swap(int dex1, int dex2)
    {
        long temp = theArray[dex1];
        theArray[dex1] = theArray[dex2];
        theArray[dex2] = temp;
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档