递归版本:
void quicksort(int start, int end, int[] arr) {
//必须是>= 因为当quicksort长度为2数组排列后会出现start>end,如果数组长度为1即start==end则直接返回
if(start>=end)return;
int j=end;
int i=start;
int base = arr[start];
while (i<j) {
//从右开始找到小于base的数index
//必须先处理j,这样才使得j==i时,arr[i]是小于base的
while (i<j&&arr[j]>base) {
j--;
}
//从左开始找到大于等于base的数index
//i的这个循环处理arr[i]==base的情况,因为一开始会有arr[i]==base,不处理则base会产生位置变化,且有可能数组中有其他等于base的数
while (i<j&&arr[i]<=base) {
i++;
}
swap(arr, i, j);
}
//这时候i==j并且保证arr[i]<=base,直接swap
swap(arr, start, i);
//分治递归
quicksort(start, i - 1, arr);
quicksort(i + 1, end, arr);
}
public void swap(int[] array, int x, int y) {
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
非递归版本:
...省略swap
//我们只需要对这个方法稍作改造,返回base的index,取消最前面的判断(放到了外层sort方法)
int quicksort(int start, int end, int[] arr) {
int j = end;
int i = start;
int base = arr[start];
while (i < j) {
//从右开始找到小于base的数index
//必须先处理j,这样才使得j==i时,arr[i]是小于base的
while (i < j && arr[j] > base) {
j--;
}
//从左开始找到大于等于base的数index
//i的这个循环处理arr[i]==base的情况,因为一开始会有arr[i]==base,不处理则base会产生位置变化,且有可能数组中有其他等于base的数
while (i < j && arr[i] <= base) {
i++;
}
swap(arr, i, j);
}
//这时候i==j并且保证arr[i]<=base,直接swap
swap(arr, start, i);
return i;
}
void sort(int[] arr) {
//本质就是递归左右坐标改成用队列存储左右坐标再一次次调用,用stack也是同理
Queue<Integer> queue = new LinkedBlockingQueue();
//初始传入整个数组
queue.add(0);
queue.add(arr.length - 1);
int l = 0, r = 0, m = 0;
while (!queue.isEmpty()) {
//先进先出,获取要排列的数组的左右坐标
l = queue.poll();
r = queue.poll();
m = quicksort(l, r, arr);
//保证传入的子数组长度起码为2,否则就不用排了
if (m - 1 > l) {
queue.add(l);
queue.add(m - 1);
}
if (m + 1 < r) {
queue.add(m + 1);
queue.add(r);
}
}
}