快速排序(quick sort)
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。(出自维基百科)
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
在这里我采用的是递归调用分区算法把序列划分成两个子序列的方法来实现快排。具体的图例在维基百科里写得非常清楚,一看就明白了。
分区算法:
首先寻找任意一个pivotIndex位置的元素作为基准元素,并把a[pivotIndex]与最后一个元素交换(swap)。借由移动小于a[pivotIndex]
的所有元素到子串行的开头,留下所有大于或等于的元素接在他们后面。在这个过程它也为基准元素找寻最后摆放的位置,也就是它回传的值。它暂时地把基准元素移到子串行的结尾,而不会被前述方式影响到。由于算法只使用交换,因此最后的数列与原先的数列拥有一样的元素。要注意的是,一个元素在到达它的最后位置前,可能会被交换很多次。
伪代码如下:
function partition(a, left, right, pivotIndex) pivotValue := a[pivotIndex] swap(a[pivotIndex], a[right]) // 把 pivot 移到結尾 storeIndex := left for i from left to right-1 if a[i] < pivotValue swap(a[storeIndex], a[i]) storeIndex := storeIndex + 1 swap(a[right], a[storeIndex]) // 把 pivot 移到它最後的地方 return storeIndex
快速排序算法实现其一:
#include <stdio.h> void swap(int *a, int *b) { int tmp; tmp = *a; *a = *b; *b = tmp; } int partition(int arr[], int left, int right, int pivotIndex) { int i,pivotValue,storeIndex; pivotValue = arr[pivotIndex]; storeIndex = left; swap(&arr[right], &arr[pivotIndex]); for (i = left; i < right; i++) { if (arr[i] < pivotValue) //升序 { swap(&arr[i],&arr[storeIndex]); storeIndex++; } } swap(&arr[right],&arr[storeIndex]); return storeIndex; } void QuickSort(int arr[], int left, int right) { int pivoValue,nRet; if (left >= right) return; pivoValue = left + 1; nRet = partition(arr,left,right,pivoValue); QuickSort(arr,left,nRet-1); QuickSort(arr,nRet+1,right); } int main() { int i,len; int arr[] = {9,7,2,5,10,7,4,3}; len = sizeof(arr)/sizeof(int); QuickSort(arr,0,len-1); for (i = 0; i < len; i++) { printf("%3d", arr[i]); } }
2013/6/15 22:31
当然,还有其它的快排的实现方法。July在它的博客里把两种实现写得非常清楚。非常推荐区读一下。
C语言里的快速排序函数:
void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
base是待排序数组的首地址;nelem是待排序的元素个数,width是待排序元素占空间的大小,fcmp是自己实现的比较函数(注意函数参数的类型),用来控制排序的顺序。
我是一名在校大学生,热爱编程,虽然起步晚了些,但我会努力的。呵呵!
数据结构 算法