点击上方“程序员小灰”,选择关注公众号
有趣有内涵的文章第一时间送达!
————— 第二天 —————
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类型元素的栈,用于存储每一次交换时的起始下标和结束下标。
每一次循环,都会让栈顶元素出栈,进行排序,并且按照基准元素的位置分成左右两部分,左右两部分再分别入栈。当栈为空时,说明排序已经完毕,退出循环。