假设给定数组为:10 3 5 18 26 6 4 13
思想:
(1)先对数组进行一趟快排(如下图1),得到支点下标par,将数组分为两个区间,红线区间和蓝线区间,如图2所示,
图1:
图2:
(2)然后利用栈,如果区间长度大于1的话,将区间两端下标放入栈中,
(3)当栈不为空就对该区间再次进行一趟快排,然后重复(2)
代码如下:
//得到支点下标
public static int partion(int[] arr,int low,int high){
int tmp = arr[low];
while(low<high){
//high位置值大于tmp,high自减
while(low<high&&arr[high]>tmp){
high--;
}
//如果low和high相等,直接退出循环,否则将high位置值赋给low位置,然后low自增
if(low == high){
break;
}else{
arr[low] = arr[high];
low++;
}
//位置值小于tmp,low自增
while(low<high&&arr[low]<tmp){
low++;
}
//如果low和high相等,直接退出循环,否则将low位置值赋给high位置,然后high自减
if(low == high){
break;
}else{
arr[high] = arr[low];
high--;
}
}
//将支点值赋给high位置
arr[high] = tmp;
//返回支点下标
return high;
}
//非递归排序
public static void quickSort(int[] arr){
Stack<Integer> stack = new Stack<>();
int low = 0;
int high = arr.length-1;
//获取支点下标
int par = partion(arr,low,high);
//如果区间长度大于1,则区间两端下标入栈
if(par>low+1){
stack.push(low);
stack.push(par-1);
}
if(par+1<high){
stack.push(par+1);
stack.push(high);
}
//栈不为空,继续操作
while(!stack.isEmpty()){
//获取栈中区间下标
high = stack.pop();
low = stack.pop();
//获取支点下标
par = partion(arr,low,high);
//如果区间长度大于1,则区间两端下标入栈
if(par>low+1){
stack.push(low);
stack.push(par-1);
}
if(par+1<high){
stack.push(par+1);
stack.push(high);
}
}
}