快速排序,顾名思义,最大的特色是速度快,其时间复杂度为O(logN*N).是什么机制导致快速排序可以达到这种效率呢?
快速排序基于这样一种思想,即:对于一个未排序的数组,按照一定的顺序(比如可以按从右到左的顺序)依次,找一个项作为关键值,遍历扫描整个数组,把这个关键值所在的项放到一个位置,使得任何在这个项左边的值都小于它,任何在这个项右边的值都大于它。一次运算可确保一个项置于其最终位置上。递归的思想体现在:认定只有一个项的数组是有序的,当数组项数>1的时候,把当前数组最右端的值做关键字,把当前数组按关键字所在的位置分成两部分,分别做快速排序。
需要指出的一个细节是:每次比较的时候最右端的数据都没有参与比较的过程中,而是当找到了其最终位置后,把最右端的数据项和当前在其最终位置处的项交换,因为这个项肯定比它大,也应该在其右边。
快速排序的代码如下:
- //---------------------------------------------------------------
- public void recQuickSort(int left,int right)//递归快排
- {
- if(right-left<=0)return;//上下限交叉时快排完成,此为递归结束条件
- else
- {
- long pivot=theArray[right];//pivot保存的是关键值,在此问题中的关键值设置为数组最右边的值
- int partition=partitionIt(left,right,pivot);//返回pivot关键字在整个数组中的最终位置
- recQuickSort(left,partition-1);//关键字左边快排
- recQuickSort(partition+1,right);//关键字右边快排
- }
- }
- //---------------------------------------------------------------
- public int partitionIt(int left,int right,long pivot)//返回关键字pivot所在的位置
- {
- int leftPtr=left-1;
- int rightPtr=right;
- while(true)//从左边其找比关键字大的项和从右边起找到的比关键字小的值交换直到交叉
- {
- while(theArray[++leftPtr]<pivot);
- while(rightPtr>0&&theArray[--rightPtr]>pivot);
- if(leftPtr>=rightPtr)break;//遍历比较,交叉后,退出
- else
- swap(leftPtr,rightPtr);//如果没有遍历则交换左右指针指向的值
- }
- swap(leftPtr,right);//最后执行的是把最右端的关键字和自己最终位置上的当前值交换
- return leftPtr;//返回左指针,指向的就是关键字的最终位置
- }
- //---------------------------------------------------------------
- public void swap(int dex1,int dex2) //swap two elements
- {
- long temp=theArray[dex1];
- theArray[dex1]=theArray[dex2];
- theArray[dex2]=temp;
- }
可以将这两个方法放在上一个手记中的ArraySh类中,应用类如下:
- package highSort;
- public class QuickSortApp {
- public static void main(String[] args)
- {
- int maxSize=16;
- ArraySh arr;
- arr=new ArraySh(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();
- }//end main
- }//end class QuickSortApp
结果显示:
- A=69 30 14 33 94 40 47 66 0 57 68 14 54 39 28 29
- A=0 14 14 28 29 30 33 39 40 47 54 57 66 68 69 94