快速排序算法

时间:2022-12-14 09:49:12

快速排序算法的思想

  快速排序算法本质上通过把一个数组划分成俩个子数组,然后递归的调用自己为每一个子数组进行快速排序来实现的,它应用了划分算法和递归思想,具体的划分算法参考http://www.cnblogs.com/iwebkit/p/7623350.html,只要把划分算法弄明白基本快速排序也就明白了。

 

 

快速排序算法的步骤

  1.把数组划分成左右俩子数组。

  2.调用自身对左数组进行排序。

  3.调用自身对右数组进行排序。

 

 

快速排序算法的枢纽选择

  在我之前写的划分算法中,我们的枢纽是自己定义的,但是在快速排序中,我们需要将数组中的某一项作为枢纽,为了便于理解,我们将待划分的右数组的最右端的数据项作为枢纽,划分完成后,将枢纽和右子数组的最左端的数据项交换位置就行了

 

 

快速算法的效率

  O(N*logN)

  

快速排序的java程序

  在程序中的注释我只写了快速排序中的划分算法和单独的划分算法的不同之处,如果想了解划分排序请看http://www.cnblogs.com/iwebkit/p/7623350.html程序中红色的代码是不同之处

package sy;

class ArrayIns{
    private long[] theArray;
    private int nElems;
    
    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.print("");
    }
    //快速排序,因为我们不想在调用的时候还要书写参数,所以将真正的快速排序放在该方法之中。
    public void quickSort(){
        recQuickSort(0,nElems - 1);
    }
    //真正的快速排序
    public void recQuickSort(int left,int right)
    {
        //当需要划分的数组只有一个数据项时,快速排序结束
        if(right - left < 1)
        {
            return;
        }
        else
        {
            //定义当前数组的最后一个数据项为枢纽
            long pivot = theArray[right];
            //调用划分算法,返回枢纽的索引值然后赋值给pivotIndex
            int pivotIndex = partitionIt(left,right,pivot);
            //递归快速算法,这个递归的是当前数组的左侧小数组
            recQuickSort(left,pivotIndex - 1);
            //递归快速算法,这个递归的是当前数组的右侧小数组
            recQuickSort(pivotIndex + 1,right);
        }
    }    
    //快速排序中的划分算法
    public int partitionIt(int left,int right,long pivot)
    {
        //定义左指针,因为内层while的theArray[++leftPtr]先自增了,所以这里先减一
        int leftPtr = left - 1;
        //定义右指针
        //这里说明一下,在划分算法中,因为内层while的theArray[++leftPtr]先自减,这里先加一为right + 1,但是在快速算法中,我们将的最后一项也数组就是索引值为right的数据项作为枢纽,所以我们取right - 1项,所以这里我们不再加一了
        int rightPtr = right;
        while(true)
        {                        
            while(leftPtr < right && theArray[++ leftPtr] < pivot)
            {
                
            }
            while(rightPtr > left && theArray[-- rightPtr] > pivot)
            {
                
            }
            //如果左右指针相遇则划分算法结束
            if(leftPtr >= rightPtr)
            {
                break;
            }
            else
            {    
                swap(leftPtr,rightPtr);
            }
        }
        //之前将数组的最后一项也就是索引值为right的数据项作为枢纽,这里我们将枢纽放在他应该在的位置也就是俩个小数组中间的位置,也就是左指针的位置
        swap(right,leftPtr);
        return leftPtr;    
    }
    //交换方法
    public void swap(int index1,int index2)
    {
        long temp = theArray[index1];
        theArray[index1] = theArray[index2];
        theArray[index2] = temp;
    }
}

class App{
    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()*199);
            arr.insert(n);
        }
        arr.display();
        arr.quickSort();
        arr.display();    
    }
}