排序_快速排序_另一种取划分点的方法

Posted S-Mustard

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序_快速排序_另一种取划分点的方法相关的知识,希望对你有一定的参考价值。

最基本的划分点由数组的最后一个值来确定,现在是将数组的最后一个值的前一个数值作为划分点,但是需要经过三项取一方法的变换,最后它位置上的值是三个中最大的。

public class ArrayIns {
    private long [] a;
    private int nElems;
    public ArrayIns(int maxSize) {
        a=new long[maxSize];
        nElems=0;
    }
    public void insert(long value) {
        a[nElems]=value;
        nElems++;
    }
    public int size() {
        return nElems;
    }
    public void display() {
        for(int j=0;j<nElems;j++) {
            System.out.print(a[j]+" ");
        }
        System.out.println();
    }
    public void quickSort() {
        recQuickSort(0, nElems-1);
    }
    //递归方法
    public void recQuickSort(int left,int right) {
        int size=right-left+1;
        //这个可以进行改进
        if(size<=3) {
            //剩下三个,就手工判断
            manualSort(left,right);
        }else{
            long median=medianOf3(left,right);
            //pivot可以进行改进
            long pivot=median;
            int partition=partitionIt(left, right, pivot);  //由划分方法return得到
            recQuickSort(left, partition-1);//前部分再划分
            recQuickSort(partition, right);//后部分再划分
        }
    }
    private long medianOf3(int left, int right) {
        //三项数据取中间大小的值作为划分点
        int center=(left+right)/2;
        if(a[left]>a[center])
            swap(left, center);
        if(a[left]>right)
            swap(left, right);
        if(a[center]>a[right])
            swap(center, right);
        swap(center, right-1);
        return a[right-1];
    }
    private void manualSort(int left, int right) {
        int size=right-left+1;
        //判断当前需要划分的数组的大小
        if(size<1)
            return;
        if(size==2) {
            if(a[left]>a[right]) {
                swap(left, right);
                return ;
            }            
        }else {
            if(a[left]>a[right-1])swap(left, right-1);
            if(a[left]>a[right])swap(left, right);
            if(a[right-1]>a[right])swap(right-1, right);
        }
        
    }
    public int partitionIt(int left,int right,long pivot) {
        int leftPtr=left;
        int rightPtr=right-1;
        while(true) {
            //左边找大于特定值的
            while( a[++leftPtr]<pivot);
            //右边找小于特定值的
            while(a[--rightPtr]>pivot);
            if(leftPtr>=rightPtr)
                break;
            else
                //交换指向的值
                swap(leftPtr, rightPtr);
        }
        swap(leftPtr, right-1);
        return leftPtr;
        
    }
    public void swap(int dex1,int dex2) {
        long temp;
        temp=a[dex1];
        a[dex1]=a[dex2];
        a[dex2]=temp;
    }

}
public class Test {

    public static void main(String[] args) {
        int maxSize=100;
        ArrayIns arrayPar=new ArrayIns(maxSize);
        arrayPar.insert(60);
        arrayPar.insert(30);
        
        arrayPar.insert(80);
        arrayPar.insert(10);
        arrayPar.insert(70);
        arrayPar.insert(90);
        arrayPar.insert(00);
        arrayPar.insert(20);
        arrayPar.insert(40);
        arrayPar.display();
        arrayPar.quickSort();
        arrayPar.display();

    }

}

 

以上是关于排序_快速排序_另一种取划分点的方法的主要内容,如果未能解决你的问题,请参考以下文章

排序_快速排序

快速排序之算法

快速排序

快速排序是一种分而治之的方法吗? [关闭]

快速排序变种实现:一次宏定义引发的熬夜事件

C语言快速排序算法及代码