基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。下图很好的描述了整个排序过程。
第一种 单向扫描方式
/**
*
* @param array
* @param sPos
* @param ePos
* @param asc :true 升序;false 降序
*/
public void quickSort(int [] array,int sPos,int ePos,boolean asc){
if(sPos<ePos){
int i=sPos-1;//定义i的起始位置
int flagItem=array[ePos];//取最后一个元素作为比较元素
boolean forward=false;
for(int j=sPos;j<ePos;j++){//j从起始位置向后扫描
forward=asc?array[j]<=flagItem:array[j]>=flagItem;//比较array[j]与flagItem
if(forward){//如果需要交换
i++; //i向前移动一个单位,交换array[i],array[j]
int tempItem=array[i];
array[i]=array[j];
array[j]=tempItem;
}
}
//扫描结束 i处于最后一个交换的元素的位置,此时array[i+1]一定是需要排在后面的,所以交换array[i+1]和array[ePos](也就是被比较的元素)
int tempItem=array[i+1];
array[i+1]=array[ePos];
array[ePos]=tempItem;
//至此,序列已经被array[ePos](也就是被比较的元素)分割成两部分。下面递归调用。
quickSort(array,sPos,i,asc);
quickSort(array,i+2,ePos,asc);
}
}
第二种 双向扫描 头尾同时相向扫描 直至相遇
/**
*
* @param array
* @param sPos
* @param ePos
* @param asc :true 升序;false 降序
*/
public void baseQuickSort(int [] array,int sPos,int ePos,boolean asc){
if(sPos<ePos){
int i=sPos; //i由头开始
int j=ePos; //j由尾开始
int flagItem=array[ePos]; //取最后一个元素作为比较元素
boolean forward = false;
boolean back = false;
while(i!=j){
forward=asc?array[i]<=flagItem:array[i]>=flagItem; //比较array[i]与flagItem
while(i!=j && forward){//i由前向后扫描,直至找到需要移动元素的位置i
i++;
forward=asc?array[i]<=flagItem:array[i]>=flagItem;
}
if(i!=j){
array[j--]=array[i];//把需要移动的元素array[i]赋值给array[j](第一次扫描是最后一个元素),并且j向前移动一个单位
}
back=asc?array[j]>=flagItem:array[j]<=flagItem;
while(i!=j && back){ //j由后向前扫描,直至找到需要移动元素的位置j
j--;
back=asc?array[j]>=flagItem:array[j]<=flagItem;
}
if(i!=j){
array[i++]=array[j];//把需要移动的元素array[j]赋值给array[i](刚才移动的元素位置),并且i向后移动一个单位
}
}
//循环结束 i==j
array[j]=flagItem;//把被比较的元素赋值给array[j](最后移动的元素位置)
baseQuickSort(array,sPos,i-1,asc);
baseQuickSort(array,i+1,ePos,asc);
}
}