手撕快排
没有自己动手写过虽然知道思想,但是实际写的时候一些边界条件控制不好,只有一个一个代码的敲上去才能学到,而且写一次会忘,那就重复写,我现在是发现自己的学习方法有问题,很多东西以为看一遍理解了思想就够了,其实毫无用处,多看几遍也无济于事,面试被问到还是说不清楚讲不明白。学东西说得深入点是学做东西,不动手做又如何掌握,梅西练习了无数次盘带,才有了被上帝亲吻的身姿和技巧,世间万物也是如此。心里要对自己说,我学会了吗,我真的学会了吗,动手试一下把。
public static void main(String[] args) {
int a[] = {5,4,3,2,1,8,2,2,5,123,12,3,35};
quickSort1(a, 0, a.length-1);
System.out.print("a");
for(int i: a){
System.out.print(i+" ");
}
}
//快速排序
public static void quickSort(int[] a, int lo, int high){
if(lo >= high) return;
int j = partion(a, lo, high);
quickSort(a, lo, j-1);
quickSort(a, j+1, high);
}
public static int partion(int[] a, int lo, int hi) {
if(lo >= hi || lo < 0 || hi <= 0) return -1;
//交换法
int v = a[lo], i = lo, j = hi+1;
while(true) {
while(a[++i] < v && i < hi);
while(a[--j] > v && lo < j);
if(i >= j) break;
int t = a[i]; a[i] = a[j]; a[j] = t;
}
a[lo] = a[j]; a[j] = v;
return j;
//挖坑法,a[lo]被保存下来了,所以相当于一个坑可以给j填,j填完了原来的位置又可以给i填,注意如果和枢值相等必须得填坑,如果不填的话就会死循环
/*int v = a[lo], i = lo, j = hi;
while(i < j){
while(i < j && a[j] >= v) j--; a[i] = a[j];
while(i < j && a[i] <= v) i++; a[j] = a[i];
}
a[i] = v;
return i;*/
}
//无递归方法
public static void quickSort1(int[] a, int lo, int high){
Stack<Integer> stack = new Stack<>();
stack.push(lo);
stack.push(high);
while(!stack.empty()){
int j = stack.pop(), i = stack.pop();
int p = partion(a, i, j);
if(i < (p-1)){
stack.push(i);
stack.push(p-1);
}
if(j > (p+1)){
stack.push(p+1);
stack.push(j);
}
}
}