现在的位置: 首页 > 综合 > 正文

简单理解的快速排序

2012年12月11日 ⁄ 综合 ⁄ 共 1429字 ⁄ 字号 评论关闭

          快速排序就是C.R.A.Hoare 于 1962年提出一种划分交换排序,它采用了分治的策略,通常称其为分治法。分治法的基本意思是:将原问题分解为若干规模更小但结构与原问题相似的子问题,递归地解答这些子问题,然后将这些子问题的解组合为原问题的解。

          快速排序的基本思想是:假设当前待排序的无序区为 A[low...high],利用分治描述如下:

(1)分解:在A[low...high]中任选一个记录作为基准(Piovt),以此为基准将当前无序区划分为左、右两个较小的子区间A[low...(pivotpos-1)]和A[(pivotpos+1)...high],并使左边子区间中所有记录的关键字均小于等于基准记录(pivot),右边的子区间中所有记录关键字均大于等于(pivot),而基准记录pivot则位于正确的位置上,无需参见后续的排序。

注意:划分的关键是求出基准记录所在位置pivotpos,划分的结果可以简单地表示为:A[low...(pivotpos-1)] <= A[pivotpos] <= A[(pivotpos+1)...high],其中pivot = A[pivotpos],low <= pivotpos <= high 。

(2)求解:通过递归调用快速排序对左、右子区间A[low...(pivotpos-1)] 和  A[(pivotpos+1)...high] 快速排序。

(3)组合:当“求解”步骤中的两个递归调用结束时,其左、右两个子区间已经有序,因而对快速排序而言,“组合”步骤无须做什么,可看做是空操作。

下面是实现代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//快速排序
void quick_sort(int a[], int low, int high)
{
	int i = 0, j = 0;
	int pivot = 0;

	if(low < high)
	{
		pivot = a[low];
		i = low;
		j = high;
		while(i < j)
		{
			while(i<j && a[j]>=pivot)	//右边放大于pivot的数
			{
				j--;
			}
			if(i < j)
			{
				a[i++] = a[j];	//将比pivot小的数放到低端
			}
			while(i<j && a[i]<=pivot)
			{
				i++;
			}
			if(i < j)
			{
				a[j--] = a[i];	//将比pivot大的数放到高端
			}
		}
		a[i] = pivot;				//将pivot放到最终的适当的位置
		quick_sort(a, low, i-1);	//对左区间递归排序
		quick_sort(a, i+1, high);	//对右区间递归排序
	}
}

int main()
{
	int data[10] = {54, 38, 96, 23, 15, 72, 60, 45, 83, -12};
	quick_sort(data, 0, 9);

	for(int i=0; i<=9; i++)
	{
		printf("%d ", data[i]);
	}
	printf("\n");

	return 0;
}

pivot的初始值为a[low]。局部变量i和j分别代表low和high的位置。按照下面的步骤进行一次交换:

(1)把比pivot小的元素移到低端(low)。

(2)把比pivot大的元素移到高端(high)。

(3)将pivot移到最终位置,此时这个位置的左边元素的值都比pivot小,而其右边元素的值都标pivot大。

(4)对左、右区间分别进行递归排序,从而把前面所进行的粗排序逐渐细化,直至最终low和high交汇。

抱歉!评论已关闭.