快速排序算法的核心思想 —— 将一个完整的,待排序的数列分割成两部分,并分别对每部分按照再分割,再排序的思想。从而实现整个数列上的排序。
代码如下:
package Sort;
import java.util.Stack;
/**
* QuickSort算法
* @author YHYR
*
*/
public class QuickSort {
public static void main(String[] args) {
int[] data = {4,7,1,5,3,6,9,0,2,8};
QuickSort qs = new QuickSort();
// qs.quickSort(data,0,data.length-1);
qs.quickSortByStack(data);
for(int i=0; i<data.length; i++)
System.out.print(data[i] + " ");
}
/**
* 通过递归的方法完成整个数组的排序
*/
public void quickSort(int[] data, int low, int high) {
int index ;
if(low<high) {
index = partition(data, low, high);
quickSort(data,low,index-1);
quickSort(data, index+1, high);
}
}
/**
* 执行一轮快排操作
* @return 返回一轮快排后,所选取的参照值对应于数组的下标
*/
public int partition(int[] data, int low, int high) {
int key = data[low];
while(low<high) {
while(low<high && data[high] >= key)
high--;
data[low] = data[high];
while(low<high && data[low] <= key)
low++;
data[high] = data[low];
}
data[low] = key;
return low;
}
/**
* 非递归,使用两个栈分别保存排序区间的上界和下届,来替换递归
*/
public void quickSortByStack(int[] data) {
Stack<Integer> startStack = new Stack<Integer>();
Stack<Integer> endStarck = new Stack<Integer>();
startStack.push(0);
endStarck.push(data.length - 1);
while(!startStack.isEmpty() && !endStarck.isEmpty()) {
int low = startStack.pop();
int high = endStarck.pop();
int mid = partition(data, low, high);
if(mid < high) {
startStack.push(mid+1);
endStarck.push(high);
}
if(low < mid) {
startStack.push(low);
endStarck.push(mid-1);
}
}
}
}
当两个位置标记low和high不相等(low<high)时,每次判断一下数列中数组下表为标记值得元素是否大于选取的参考值key,当data【high】> key,则不作加入操作,直接向前移动high标记,即high - -;直到出现data【high】< key 时,把该值插入到key所在的数组位置中;此时data【high】即为空缺的。当从low开始判断,原理如上,直到出现 data【low】> key 时,把data【low】插入到之前空缺的data【high】处。反复如此,直到low == high时,即完成了第一轮快排。
需要注意的是:在判断和筛选的时候,只需要判断当前判断的值和 key 的大小,如果大,在置于key 之后,反之,放在key之前。不用考虑在往key值前后插入的时候具体的插入位置。只要保证key之前的值都小于key,key之后的值都大于key即可。所以在此算法中,用到了分步判断,即:每当判断完key和data【high】时,就会产生一个空缺位置,同时把符合条件的data【high】插入到key处;当进行判断key和data【low】时,则把符合条件的data【low】插入之前的空缺即可。而最终key的位置即就是当low==high时的位置。