点击上方“程序员小灰”,选择关注公众号
有趣有内涵的文章第一时间送达!
————— 第二天 —————
public class QuickSort {
-
public static void quickSort(int[] arr, int startIndex, int endIndex) {
-
// 递归结束条件:startIndex大等于endIndex的时候
-
if (startIndex >= endIndex) {
-
return;
-
}
-
// 得到基准元素位置
-
int pivotIndex = partition(arr, startIndex, endIndex);
-
// 用分治法递归数列的两部分
-
quickSort(arr, startIndex, pivotIndex - 1);
-
quickSort(arr, pivotIndex + 1, endIndex);
-
}
-
-
-
private static int partition(int[] arr, int startIndex, int endIndex) {
-
// 取第一个位置的元素作为基准元素
-
int pivot = arr[startIndex];
-
int left = startIndex;
-
int right = endIndex;
-
// 坑的位置,初始等于pivot的位置
-
int index = startIndex;
-
-
//大循环在左右指针重合或者交错时结束
-
while ( right >= left ){
-
//right指针从右向左进行比较
-
while ( right >= left ) {
-
if (arr[right] < pivot) {
-
arr[left] = arr[right];
-
index = right;
-
left++;
-
break;
-
}
-
right--;
-
}
-
//left指针从左向右进行比较
-
while ( right >= left ) {
-
if (arr[left] > pivot) {
-
arr[right] = arr[left];
-
index = left;
-
right--;
-
break;
-
}
-
left++;
-
}
-
}
-
arr[index] = pivot;
-
return index;
-
}
-
-
-
public static void main(String[] args) {
-
int[] arr = new int[] {4,7,6,5,3,2,8,1};
-
quickSort(arr, 0, arr.length-1);
-
System.out.println(Arrays.toString(arr));
-
}
}
public class QuickSort {
-
public static void quickSort(int[] arr, int startIndex, int endIndex) {
-
// 递归结束条件:startIndex大等于endIndex的时候
-
if (startIndex >= endIndex) {
-
return;
-
}
-
// 得到基准元素位置
-
int pivotIndex = partition(arr, startIndex, endIndex);
-
// 根据基准元素,分成两部分递归排序
-
quickSort(arr, startIndex, pivotIndex - 1);
-
quickSort(arr, pivotIndex + 1, endIndex);
-
}
-
-
-
private static int partition(int[] arr, int startIndex, int endIndex) {
-
// 取第一个位置的元素作为基准元素
-
int pivot = arr[startIndex];
-
int left = startIndex;
-
int right = endIndex;
-
-
while( left != right) {
-
//控制right指针比较并左移
-
while(left<right && arr[right] > pivot){
-
right--;
-
}
-
//控制right指针比较并右移
-
while( left<right && arr[left] <= pivot) {
-
left++;
-
}
-
//交换left和right指向的元素
-
if(left<right) {
-
int p = arr[left];
-
arr[left] = arr[right];
-
arr[right] = p;
-
}
-
}
-
-
//pivot和指针重合点交换
-
int p = arr[left];
-
arr[left] = arr[startIndex];
-
arr[startIndex] = p;
-
-
return left;
-
}
-
-
-
public static void main(String[] args) {
-
int[] arr = new int[] {4,7,6,5,3,2,8,1};
-
quickSort(arr, 0, arr.length-1);
-
System.out.println(Arrays.toString(arr));
-
}
}
和挖坑法相比,指针交换法在partition方法中进行的元素交换次数更少。
下面我们来看一下代码:
public class QuickSortWithStack {
-
public static void quickSort(int[] arr, int startIndex, int endIndex) {
-
// 用一个集合栈来代替递归的函数栈
-
Stack<Map<String, Integer>> quickSortStack = new Stack<Map<String, Integer>>();
-
// 整个数列的起止下标,以哈希的形式入栈
-
Map rootParam = new HashMap();
-
rootParam.put("startIndex", startIndex);
-
rootParam.put("endIndex", endIndex);
-
quickSortStack.push(rootParam);
-
-
// 循环结束条件:栈为空时结束
-
while (!quickSortStack.isEmpty()) {
-
// 栈顶元素出栈,得到起止下标
-
Map<String, Integer> param = quickSortStack.pop();
-
// 得到基准元素位置
-
int pivotIndex = partition(arr, param.get("startIndex"), param.get("endIndex"));
-
// 根据基准元素分成两部分, 把每一部分的起止下标入栈
-
if(param.get("startIndex") < pivotIndex -1){
-
Map<String, Integer> leftParam = new HashMap<String, Integer>();
-
leftParam.put("startIndex", param.get("startIndex"));
-
leftParam.put("endIndex", pivotIndex -1);
-
quickSortStack.push(leftParam);
-
}
-
if(pivotIndex + 1 < param.get("endIndex")){
-
Map<String, Integer> rightParam = new HashMap<String, Integer>();
-
rightParam.put("startIndex", pivotIndex + 1);
-
rightParam.put("endIndex", param.get("endIndex"));
-
quickSortStack.push(rightParam);
-
}
-
}
-
}
-
-
private static int partition(int[] arr, int startIndex, int endIndex) {
-
// 取第一个位置的元素作为基准元素
-
int pivot = arr[startIndex];
-
int left = startIndex;
-
int right = endIndex;
-
-
while( left != right) {
-
//控制right指针比较并左移
-
while(left<right && arr[right] > pivot){
-
right--;
-
}
-
//控制right指针比较并右移
-
while( left<right && arr[left] <= pivot) {
-
left++;
-
}
-
//交换left和right指向的元素
-
if(left<right) {
-
int p = arr[left];
-
arr[left] = arr[right];
-
arr[right] = p;
-
}
-
}
-
-
//pivot和指针重合点交换
-
int p = arr[left];
-
arr[left] = arr[startIndex];
-
arr[startIndex] = p;
-
-
return left;
-
}
-
-
public static void main(String[] args) {
-
int[] arr = new int[] {4,7,6,5,3,2,8,1};
-
quickSort(arr, 0, arr.length-1);
-
System.out.println(Arrays.toString(arr));
-
}
}
和刚才的递归实现相比,代码的变动仅仅在quickSort方法当中。该方法中引入了一个存储Map类型元素的栈,用于存储每一次交换时的起始下标和结束下标。
每一次循环,都会让栈顶元素出栈,进行排序,并且按照基准元素的位置分成左右两部分,左右两部分再分别入栈。当栈为空时,说明排序已经完毕,退出循环。