今天复习了一下快排,感觉还是挺多收货的.
快排的思想
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
该方法的基本思想是:
1.先从数列中取出一个数作为基准数pivot。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
解法
根据以上的介绍,我写了最基础的快排(升序),即用最左边的元素作为pivot。在oj上过不了。
1 | private static void quicksortbasic(int[] put, int left, int right){ |
挖坑法:
1 | private static void wakengfa(int[] put, int left, int right){ |
对挖坑填数进行总结
1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
2.j—由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。
在挖坑法中,考虑到已经排序好的逆序数组(降序数组)会造成递归栈溢出的可能
{9,8,7,6,5,4,3,2,1,0}
第一次“填坑” 会变成 {0,8,7,6,5,4,3,2,1,0}
第一次结束:{0,8,7,6,5,4,3,2,1,9}
递归开始:
{0,8,7,6,5,4,3,2,1} {9}
可以想见当数组长度很长的时候,是有可能会溢出的。因此一般会选择中间点或者是中位数作为pivot,保证递归两边数量差不多,效率最高。
别的版本
附上快排另一个版本,和挖坑法类似,但是比挖坑法难理解.
1 | private static void quicksortmiddle(int[] put, int left, int right){ |
附上swap和调用代码
1 | public static void quickSortenter(int[] put){ |
Main函数
1 | int a[] = {3,2,1,4,5,6}; |
reference:
https://blog.csdn.net/morewindows/article/details/6684558
测试oj: