快排的核心思想为每次确定一个数的位置,并使其左边的数均小于该数,右边的数均大于该书。之后对其左右两边进一步执行相同操作,直到排序结束。
程序主体为:
public static void quickSort(int[] nums, int begin, int end) { if (begin < end) { int mid = partition(nums, begin, end); quickSort(nums, begin, mid - 1); quickSort(nums, mid + 1, end); } }
Partition执行完成后,确定了一个数(这里默认为输入数组的第一个数)的位置。
以数组nums={5,2,7,3,6}为例:
I.quickSort(nums,0,4)
调用quickSort(nums,0,4)后,mid=partition(nums,0,4)=2,执行完partition后的数组分布如所示。接下来执行quickSort(nums,0,1),quickSort(3,4)。
II. quickSort(nums,0,1)&quickSort(nums,3,4)
quickSort(nums,0,1)过程中,mid=partition(nums,0,1)=1,完成partition后的数字分别如III左所示,得到最终结果。该部分接下去执行quickSort(nums,0,0)及quickSort(nums,1,1),在quickSort(nums,0,0)及quickSort(nums,1,1)中,(begin<end) == false,quickSort停止执行。
quickSort(nums,3,4)第类似于quickSort(nums,0,1)
具体流程如下,其中红色表示partition开始的位置,黄色表示partition完成后数字放置的位置:
Partition的功能为为某数找到指定位置。Partition(nums,0,4)的执行流程如下:
1. 基点为0,nums[0]=5。Int x = 5。将两个指针指向nums[1]和nums[4],如图中过程I
2. 先看右边的执行,6>5,不执行动作,右指针左移,如图中过程II。
3. 再看右指针,3<5,将3至于nums[0],nums[0]=3,如III。
4. 开始看左指针,2<5,不执行动作,左指针右移,如图中过程IV
5. 左指针指向nums[3]=7>x,交换左右指针中的值,如图中过程V
6. 右指针左移,与左指针重叠,循环结束,将x至于其中,完成partition。如图中VI所示
Partition函数:
public static int partition(int[] nums, int begin, int end) { int i = begin, j = end; int x = nums[i]; while (i < j) { while (i < j && x < nums[j]) --j; if (i < j) nums[i++] = nums[j]; while (i < j && nums[i] < x) ++i; if (i < j) nums[j--] = nums[i]; } nums[i] = x; return i; }
根据以上可知,快排的过程其实就是“不停调用partition对问题进行切割,不断减小问题规模”的过程。快排的非递归写法可通过stack存放partition中所需的begin及end完成。
整体代码:
import java.util.Stack; public class Quick { public static int partition(int[] nums, int begin, int end) { int i = begin, j = end; int x = nums[i]; while (i < j) { while (i < j && x < nums[j]) --j; if (i < j) nums[i++] = nums[j]; while (i < j && nums[i] < x) ++i; if (i < j) nums[j--] = nums[i]; } nums[i] = x; return i; } // 递归 public static void quickSort(int[] nums, int begin, int end) { if (begin < end) { int mid = partition(nums, begin, end); quickSort(nums, begin, mid - 1); quickSort(nums, mid + 1, end); } } // 非递归 public static void quickSort2(int[] nums, int begin, int end) { Stack<Integer> stack = new Stack<Integer>(); int k = 0; if (begin < end) { stack.push(begin); stack.push(end); while (!stack.empty()) { int j = stack.pop(); int i = stack.pop(); k = partition(nums, i, j); if (i < k - 1) { stack.push(i); stack.push(k - 1); } if (k + 1 < j) { stack.push(k + 1); stack.push(j); } } } } public static void main(String[] args) { // TODO Auto-generated method stub int[] arr = { 3, 5, 9, 7, 1, 6, 13, 22, 2 }; quickSort2(arr, 0, arr.length - 1); for (int i : arr) System.out.print(i + " "); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/miaoyunzexiaobao/article/details/47781079