Quick Sort 快速排序
一、基本思想
通过使用一个基准值将列表分为2个子列表,具体的过程是:
将基准值放在正确的位置上,在一个子列表中放入小于基准值的元素,另一个子列表中放入大于基准值的元素。
这就是快速排序(Quick Sort)的思想。
快排算法提供了目前已知最快的排序技术,除了某些极其特殊的情况下之外,快速排序徐几乎适用于所有场合。
二、算法描述
快速排序使用一系列递归调用将列表分为若干越来越小的子列表,这些子列表位于基准值(pivot)左右。每个递归步骤根据作为列表中心点值的基准进行选择。分割算法完成交换,从而使基准值在元素最终排序后被放置在列表中的正确位置上。
此时,下子列表只含有小于或等于基准值的元素,而上子列表只含有大于或等于基准值的元素。原始数组在递归下降之后变为有序数组。需要注意的是:归并排序对元素排序时还会将元素放置到临时数组中。而快速排序是通过在子列表之内交换元素对序列重新排序,所以快速排序是一种“原地置换(in-place)算法”。
三、示例代码
public class Quick
{
public static void QuickSort(int[] arr)
{
// call QSort
QSort(arr, 0, arr.Length);
}
private static void QSort(int[] arr, int first, int last)
{
// index of the pivot
int pivotLoc;
// temp used for an exchange in a 2-elements list,
int temp;
// if the range is not at least two elements, return
if (last - first <= 1)
{
return;
}
// if sublist has two elements, compares arr[first] and
// arr[last-1] and exchange if necessary
else if (last - first == 2)
{
if (arr[last - 1] < arr[first])
{
temp = arr[last - 1];
arr[last - 1] = arr[first];
arr[first] = temp;
}
return;
}
else
{
pivotLoc = PivotIndex(arr, first, last);
// make the recursive call
QSort(arr, first, pivotLoc);
// make the recursive call
QSort(arr, pivotLoc + 1, last);
}
}
private static int PivotIndex(int[] arr, int first, int last)
{
// index for the midpoint of [first,last] and
// the indices that scan the index range in tandem
int mid, scanUp, scanDown;
// pivot value and array used for exchange
int pivot, temp;
// empty list
if (first == last)
{
return last;
}
else if (first == last - 1)
{
// 1-elements sublist
return first;
}
else
{
mid = (first + last) / 2;
pivot = arr[mid];
// exchange the pivot and the low end of the range
// and initialize the indices scanUp and scanDown
scanUp = first + 1;
scanDown = last - 1;
// manage the indices to locate elements that are in
// the wrong sublists; stop when scanDwon <= scanUp
for (; ; )
{
// move up the lower sublist; continue so long as
// scanUp is less than or equal to scanDown and
// the array value is less than pivot
while (scanUp <= scanDown && arr[scanUp] < pivot)
{
scanUp++;
}
// move down the upper sublist so long as the array
// value is greater than the pivot
while (arr[scanDown] > pivot)
{
scanDown--;
}
// if indices are not in their sublists, partition complete
if (scanUp >= scanDown)
{
break;
}
// indices are still in their sublists and identity
// two elements in wrong sublists;exchanges
temp = arr[scanUp];
arr[scanUp] = arr[scanDown];
arr[scanDown] = temp;
scanUp++;
scanDown--;
}
// copy pivot to index (scanDwon) that partitions
// sublists and return scanDwon
arr[first] = arr[scanDown];
arr[scanDown] = pivot;
return scanDown;
}
}
}
四、效率分析
不稳定。
空间复杂度:O(1)
时间复杂度:O(nlog2n)
最坏情况:O(n2),要排序数组基本有序,基准值每次取最大(最小)元素,退化为冒泡。
最好情况:O(nlog2n) 基准值两边元素个数基本相同.
作者:樊勇
出处:http://www.cnblogs.com/fanyong/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
我的联系方式:fanyong@gmail.com
个人独立博客:www.fy98.com
浙公网安备 33010602011771号