《数据结构--排序》之快速排序

1.序

快速排序是一种借助“交换”的方式,对冒泡排序的一种改进的排序算法。


2.冒泡排序

不用说,学到的第一个排序算法就是冒泡排序(bubble sort)。代码如下:

/*
 * 对sq+1,sq+2,sq+3,...,sq+length进行冒泡排序
 */
void BubbleSort(int *sq,int length){
	int tmp;
	for(int i=length;i>1;i--){
		for(int j=1;j<i;j++){
			if(sq[j]>sq[j+1]){
				tmp=sq[j];
				sq[j]=sq[j+1];
				sq[j+1]=tmp;
			}
		}
	}
}
冒泡排序时间复杂度是 O(n^2),效率比较低,在最坏情况下需要进行  n(n-1)/2 次比较,并作同等数量级的记录移动。


3.快速排序

快速排序对冒泡排序有较大改进,它的基本思想是:通过一趟排序将待排序记录分割成两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

假设待排序的序列为 r[low],r[low+1],......,r[high],任选一个记录,通常是第一个记录 r[low] 为枢轴(pivot),然后将所有关键字比枢轴大的记录都安置在枢轴之后,所有比枢轴小的记录都安置在枢轴前面,以枢轴最后落点位置pos为分界点,将序列分割成两个序列:r[low],r[low+1],.....,r[pos-1]和r[pos+1],r[pos+2],.....,r[high],这个过程称为一趟快速排序或一次划分。具体做法如下代码所示:

/*
 * 对记录进行一趟快速排序(划分)
 */
static int Partion(int *sq,int low,int high){
	/*以第一个记录为枢轴,并非一定要第一个记录作枢轴*/
	int pivotkey=sq[low];

	while(low<high){
		/*从后往前找到一个比枢轴小的记录调整到前面*/
		while( (low<high)&&(sq[high]>pivotkey) ){
			high--;
		}
		sq[low]=sq[high];

		/*从前往后找到一个比枢轴大的记录调整到后面*/
		while( (low<high)&&(sq[low]<pivotkey) ){
			low++;
		}
		sq[high]=sq[low];
	}
	/*此时low==high,low指向的位置就是枢轴应该在的位置*/
	sq[low]=pivotkey;
	return low;
}

对记录一趟排序后剩下两个记录序列,又可以分别对这两个序列进行划分,同样的方法,递归实现,得到快速排序代码如下:

/*
 * 递归进行划分,直到有序
 */
static void Qsort(int *sq,int low,int high){
	if(low<high){
		int pivot=Partion(sq,low,high);
		Qsort(sq,low,pivot-1);
		Qsort(sq,pivot+1,high);
	}
}
/*
 * 对sq+1,sq+2,sq+3,...,sq+length 进行快速排序
 */
void QuickSort(int *sq,int length){
	Qsort(sq,1,length);
}

快速排序时间复杂度为 O(nlogn),平均时间复杂度低,但是最坏情况的话就沦落到冒泡排序


4.总结

快速排序是目前系统排序用得最多的排序算法,平均时间复杂度是最好的,个人觉得快速排序要用到栈,对于排序的规模是否有限制呢?

你可能感兴趣的:(数据结构,算法,PIVOT)