分治策略实现快速排序法

说到算法,暑假就要去实习了,这时才感觉到数据结构和算法的重要性,虽然大二时候已经学过,但是基本用不到,导致现在基本忘了,现在重新拾起,重新把以前学过的和没有学过的算法都理一遍实现一遍!!!

给自己一个任务——每天一个算法!!!

数量级O(n longn)的排序方法中,其平均性能最好。就平均时间而言,是目前被认为最好的一种内部排序方法,它是不稳定的。

基本思想是:

1.先从数组中取一个数作为基准数。

将比这个基准数大的数全放到它的右边,小于它的数全放到它的左边,等于它的数位置不变,在这个分区过程结束时,该基准数的位置就处于数组中间的位置。

3.再对左右区间重复第二步(递归进行),直到各区间只有一个数,这时排序完毕。

关于取哪个数作为基准数,,这个不建议取第一个,建议随机取一个数作为基准数,这样取只是为了防止极端现象,可以防止当一个数组基本有序时,如果还是取第一个,那么快排的时间复杂度则退化为O(n),如果每次都随机取一个数为基准数,那么可以避免这种现象。

看看演示图:

下面为更好理解,我就以取第一个数为基准数来演示:

把整个序列看做一个数组,把第零个位置作为pivotNum,先从后面往前找,即首先和最后一个比,如果比它小交换,比它大不做任何处理,交换了以后再从前往后找,即和第一个元素比,比它小不交换,比他大交换。这样循环往复,一趟排序完成,左边就是比中轴pivotNum小的,右边就是比中轴pivotNum大的,然后再用分治法,分别对这两个独立的数组再进行快速排序,如此往复循环,直至每个数组中只有一个元素才排序完成。

进行排序一趟的代码为:

public static int sort(int[] data,int left,int right){//每次进行一趟排序int pivotNum = data[left];while(left<right){while(left<right && data[right]>=pivotNum){right–;}data[left] = data[right];//将比轴点小的数移到左端,此时right位相当于空,等待左边比pivotNum大的数赋予它while(left<right && data[left]<=pivotNum){left++;}data[right] = data[left];//将比轴点大的数移到右端,此时left位相当于空,等待右边比pivotNum小的数赋予它}//此时left==right,完成了一躺排序,此时left位相当于空,等待轴点那个数pivotNum补上 data[left] = pivotNum;//此时返回的lefr即为中间的位置return left;}递归的实现快速排序:public static void quickSort(int[] nums,int left,int right){if(isEmpty(nums))return;if(left<right){//middle作为中间的位置,比它所在位置的元素小的元素在左边作为一个数组再进行排序,比它所在位置的元素大的元素在右作为一个数组进行排序int middle = sort(nums, left, right);//将list数组进行一分为二,然后分别递归排序//对左、右数组递归调用快速排序,直到排序完成quickSort(nums, left, middle-1);quickSort(nums, middle+1, right);}}

最后贴下整个代码:public class QuickSort {public static int sort(int[] data,int left,int right){//每次进行一趟排序int pivotNum = data[left];while(left<right){while(left<right && data[right]>=pivotNum){right–;}data[left] = data[right];//将比轴点小的数移到左端,此时right位相当于空,等待左边比pivotNum大的数赋予它while(left<right && data[left]<=pivotNum){left++;}data[right] = data[left];//将比轴点大的数移到右端,此时left位相当于空,等待右边比pivotNum小的数赋予它}//此时left==right,完成了一躺排序,此时left位相当于空,等待轴点那个数pivotNum补上 data[left] = pivotNum;//此时返回的lefr即为中间的位置return left;}public static void quickSort(int[] nums,int left,int right){if(isEmpty(nums))return;if(left<right){//middle作为中间的位置,比它所在位置的元素小的元素在左边作为一个数组再进行排序,比它所在位置的元素大的元素在右作为一个数组进行排序int middle = sort(nums, left, right);//将list数组进行一分为二,然后分别递归排序//对左、右数组递归调用快速排序,直到排序完成quickSort(nums, left, middle-1);quickSort(nums, middle+1, right);}}public static boolean isEmpty(int[] nums){if(nums.length==0){return true;}return false;}}测试:

输入:17 31 40 26 35 36 25 12 2 38

输出:2 12 17 25 26 31 35 36 38 40

思想如钻子,必须集中在一点钻下去才有力量

分治策略实现快速排序法

相关文章:

你感兴趣的文章:

标签云: