码迷,mamicode.com
首页 > 编程语言 > 详细

分治策略实现快速排序法

时间:2015-05-27 14:07:35      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:快速排序   算法   递归   分治   java   

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

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

快速排序算法:是对冒泡排序的一种改进,若初始记录序列按关键字pivotNum有序或基本有序,则将会蜕化为冒泡排序,此时时间复杂度为O(n2)。否则其平均时间复杂度为O(n longn) ,它使用的是递归原理,在所有同数量级O(n longn) 的排序方法中,其平均性能最好。就平均时间而言,是目前被认为最好的一种内部排序方法,它是不稳定的。

基本思想是

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

2.分区过程,先从后往前找,再从前往后找,将比这个基准数大的数全放到它的右边,小于它的数全放到它的左边,等于它的数位置不变,在这个分区过程结束时,该基准数的位置就处于数组中间的位置

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

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

看看演示图:

技术分享

技术分享

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

技术分享

技术分享

把整个序列看做一个数组,把第零个位置作为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



分治策略实现快速排序法

标签:快速排序   算法   递归   分治   java   

原文地址:http://blog.csdn.net/u010687392/article/details/46044043

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!