快速排序

快速排序

简介

快速排序是一种划分交换排序。它采用了一种分治的策略,通常称其为分治法。与冒泡排序同属于交换排序。

算法原理

从数组中取出一个数作为基准数,通常是第一个元素,将比这个数大的元素放在它的右边,比他小的元素放在它的左边,然后对左右区间进行以上操作。直到数组变为有序数组。

代码实现

代码实现有几种方式,第一种是找到一个符合条件的元素就交换,不容易理解(至少在我看来是这样)。
第二种是找到符合条件的元素进行赋值,通过一个临时变量和几次赋值操作完成元素的交换。与第一种相比容易理解一些。代码如下:

	public static int[] quickSort(int a[], int startIndex, int endIndex)  
	{  
		if(startIndex <endIndex){//数组长度大于1时进行递归
			int i=startIndex;
		    int j=endIndex;
		    int temp=a[i];//将a[i]这个元素挖空,等待其他数据填入,并将a[i]的值取出存入到临时变量中
		    while(i<j){   //控制每次递归前后两个坐标相遇的点
		    	while(i<j&&a[j]>=temp)//从右向左找到第一个比temp小的值
		    	{
		    		j--;
		    	}
		    	if(i<j)
		    	{
		    		a[i]=a[j];//将a[j]的值填入a[i],此时a[j]被挖空
		    	}
		    	while(i<j&&a[i]<=temp)//从左到右找到第一个比temp大的值
		    	{
		    		i++;
		    	}
		    	if(i<j)
		    	{
		    		a[j]=a[i];//将这个比temp小的值填入a[j],此时a[i]被挖空
		    	}
		    }
		    a[i]=temp;//每次循环结束时,a[i]都处于挖空的状态,将temp填入a[i]
		    quickSort(a, startIndex, i-1);
		    quickSort(a, i+1, endIndex);
		}
		return a;  
	}  

代码中,外面的while循环,每次执行时,控制的是前后两个‘指针’,指针相遇时跳出循环,内循环负责查找元素,并赋值。每次递归在理想状态下两个内循环构与临时变量temp以及a[i]形成一次三个元素的交换(4,5,2,6.数组依次变成2,5,2,6; 2,5,5,6; 2,4,5,6.)。当然交换的次数可能大于三次,可能是两个元素的交换(如3,2,4,5只需要3和2交换位置),也可能只有一次循环体外的赋值操作(数组本身就是有序的)。

第三种方式最容易理解,采用前后两个‘指针’,后面的指针先移动,找到第一个小于基准数的元素,前面的指针后移动,找到第一个大于基准数的元素,交换着两个‘指针’所指的元素。直到两个指针相遇,交换当前元素与基准数。注意一定要后面的指针先移动

	public static int [] quickSort2(int a[],int startIndex,int endIndex){
		if(startIndex<endIndex){
			int i=startIndex;
			int j=endIndex;
			int temp=a[i];//将a[i]存储到临时变量里面
			int t;//交换用的临时变量
			while(i<j){
				while(i<j&&a[j]>=temp){//从右边开始找到第一个小于temp的值
					j--;
				}
				while(i<j&&a[i]<=temp){//从左边开始找到第一个大于temp的值
					i++;
				}
				if(i<j){//交换两个值
					t=a[j];
					a[j]=a[i];
					a[i]=t;
				}				
			}
			a[startIndex]=a[i];//跳出循环时,此时的i和j相等,交换基准数与a[i]的值。
			a[i]=temp;
			quickSort2(a, startIndex, i-1);
			quickSort2(a, i+1, endIndex);
		}		
		return a;
	}

有人说“第三种方式,不是快速排序,快速排序每次交换都是跟基准数交换”。对此观点,很不赞同,难道非要和书上一模一样的才是快速排序吗,快速排序的中心思想就是找到基准数的最终位置,再用二分思想和递归对左右两个数组进行排序。这种方式并没有违背算法的中心思想,所以应该是正确的,而且交换的次数会比传统方式的次数少。

posted @ 2017-07-19 22:43  Lee_Shuai  阅读(172)  评论(0编辑  收藏  举报