/** * 递归 */ privatestaticvoidquick(int[] a, int low, int high){ if (low >= high) return; intp= partition1(a, low, high); quick(a, low, p - 1);//左边分区 quick(a, p + 1, high);//右边分区 }
/** * 用于分区 单边循环 * @param a 目标数组 * @param low 左指针 * @param high 右指针 * @return 返回基准点元素所在的正确索引,用它确定下一轮分区的边界 */ privatestaticintpartition1(int[] a, int low, int high){ //1. intpv= a[high]; inti= low; intj= low; while (j < high){ //2. if (a[j] < pv){ swap(a, i, j); //3. i++;//维护小于基准点的边界 } j++; } //4. swap(a, i ,j); System.out.println(Arrays.toString(a) + " i ==>" + i); //返回值表示了基准点元素所在的正确索引,用它确定下一轮分区的边界 return i; }
/** * 置换函数 */ privatestaticvoidswap(int[] a, int i, int j){ inttemp= a[i]; a[i] = a[j]; a[j] = temp; } }
/** * 递归 */ privatestaticvoidquick(int[] a, int low, int high){ if (low >= high) return; intp= partition2(a, low, high); quick(a, low, p - 1);//左边分区 quick(a, p + 1, high);//右边分区 }
/** *双边 */ privatestaticintpartition2(int[] a, int low, int high){ intpv= a[low]; inti= low; intj= high; while (i<j){ //j 从右往左找小的 //1. 必须先从 j 开始 从右往左 // 这是因为 如果先从 i 找 i会停止在比基准点大的元素上 // 同时 j 也会停留在这上面 // 最后一步就会将 这个比基准点大的元素 移动到基准点上 while (i < j && a[j] > pv){ j--; } //i 从左往右找大的 //1. 这里加上等于号 是因为 a[i] 的初始值就是 pv 即左侧基准点;不加的则i始终不动 //2. 加上 i < j 是为了防止后续的序列中已经排好序了 造成i越过了j ;上同 while (i < j && a[i] <= pv){ i++; }
swap(a, i , j); } swap(a, low, i); System.out.println(Arrays.toString(a) + " i ==>" + i); return i; }
/** * 置换函数 */ privatestaticvoidswap(int[] a, int i, int j){ inttemp= a[i]; a[i] = a[j]; a[j] = temp; } }