这篇文章介绍 一个非常流行并且高效的排序算法:QuickSort。
该算法优于 MergeSort 的一点是它在原位上排序,即对于被排序的元素,不需要辅助的存储空间。
在介绍 QuickSort 之前,需要先介绍划分算法,它是 QuickSort 的基础。
1. Split
设 A[low...high] 是一个包含 n 个数的数组,并且 x = A[low]。我们考虑重新安排数组 A 中的元素的问题,使得小于或等于 x 的元素在 x 的前面,随后 x 又在所有大于它的元素的前面。
经过数组中的元素改变排列后,对于某个 w,low ≤ w ≤ high,x 在 A[w] 中。
例如,假设 A = { 5, 3, 9, 2, 7, 1, 8 },low = 1,high = 7,则经过重新排列其中的元素后,得到 A = { 1, 3, 2, 5, 7, 9, 8 },这样元素重新排列后,w = 4.这种重排列行动也称为围绕 x 的拆分或划分,x 称为主元或拆分元素。
如果元素 A[j] 既不小于 A[low...j-1] 中的元素,也不大于 A[j+1...high]中的元素,则称其处在一个适当位置或正确位置。
用 x (x ∈ A) 作为主元划分数组 A 后,x 将处于一个正确位置。
过程 Split
输入 数组 A[low...high]
输出 (1) 如果有必要,输出重新排列的数组 A
(2) 划分元素 A[low] 的新位置 w
算法描述
i ← low
x ← A[low]
for j ← low + 1 to high
if A[j] ≤ x then
i ← i + 1
if i ≠ j then 互换 A[i] 和 A[j]
end if
end for
互换 A[low] 和 A[i]
w ← i
return A 和 w
整个算法的执行过程中,始终保持两个索引 i 和 j,并在初始时分别设置为 low 和 low + 1,这两个索引从左向右移动,使得经过每个 for 循环迭代后,有:
(1) A[low] = x
(2) A[k] ≤ x,对于所有 k,low ≤ k ≤ i
(3) A[k] > x,对于所有 k,i < k ≤ j
算法对所有元素扫描后,用 A[i] 与主元交换,这样所有小于或等于主元的元素处在它的左边,并且所有大于主元的元素落在它的右边。
private static int split(int[] array, int low, int high)
{
int splitIndex = low;
int lowValue = array[low];
for (int i = low + 1; i <= high; i++)
{
if (array[i] > lowValue)
continue;
splitIndex++;
if (splitIndex != i)
{
array[splitIndex] = array[splitIndex] + array[i];
array[i] = array[splitIndex] - array[i];
array[splitIndex] = array[splitIndex] - array[i];
}
}
if (low != splitIndex)
{
array[low] = array[low] + array[splitIndex];
array[splitIndex] = array[low] - array[splitIndex];
array[low] = array[low] - array[splitIndex];
}
return splitIndex;
}
2. QuickSort
算法 QuickSort 在它的最简单的形式中能概括如下:
要排序的元素 A[low...high] 通过算法 Split 重新排列元素,使得原先在 A[low] 中的主元占据其正确的位置 A[w],并且所有小于或等于 A[w] 的元素所处的位置为 A[low...w-1],而所有大于 A[w] 的元素所处的位置是 A[w+1...high]。
子数组 A[low...w-1] 和 A[w+1...high] 递归地排序,产生整个排序数组。
过程 QuickSort
输入 n 个元素的数组 A[1...n]
输出 按非降序排列的数组 A
算法描述 quickSort(A, low, high)
if low < high then
w ← Split(A, low, high) { w 为 A[low] 的新位置}
quickSort(A, low, w-1)
quickSort(A, w+1, high)
end if
public static void quickSort(int[] array, int low, int high)
{
if (low > high)
return;
int splitIndex = split(array, low, high);
quickSort(array, low, splitIndex - 1);
quickSort(array, splitIndex + 1, high);
}
分享到:
相关推荐
合并排序算法和快速排序算法采用了采用分治法、递归的方法,将时间复杂度降为O(nlogn)。在本次实验中将数据量提到5万的时候,该类算法运行时间仍在几毫秒左右,而上面的3种算法运行时间已经到达十几秒左右,效率...
快速排序,使用分治算法,绝对AC,使用C++算法,没有使用sort,时间复杂度O(n logn)
用分治算法的思想,加上递归 实现快速排序
包括所有算法分析设计的实验(java快速排序。归并排序,分治算法,回溯算法,n后问题)
分治法的应用,快速排序是其中一种。注释便于读者明白。
分治法的另外一种排序算法,快速排序。有注释,便于阅读,因为交换时使用的引用,暂时归为C++,C语言版稍后奉上。
采用递归分治算法写的快速排序 这是为上机考试准备的,呵呵
实现并验证合并排序算法; 实现并验证快速排序算法(参考习题5.2第7a题,P140); 用递归与分治的方法设计并实现寻找第k小元素算法
这个代码是利用快速排序算法,求第K大的数。 快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后...
算法实验(java快速排序。归并排序,分治算法,回溯算法,n后问题)
java 快速排序 折半查找的界面实现 (递归与分治法)
算法分析第二单元员 分治法的学习 中的经典问题3 也叫做归并排序
实现并验证合并排序算法; Ex2:实现并验证快速排序算法 Ex3:用递归与分治的方法设计并实现寻找第k小元素算法
二分搜索算法和快速排序算法及分治策略.doc
算法的学习,分治
在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的...这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……
使用快速排序算法实现对n个元素进行排序。 由文件input.txt提供输入数据,输出到文件output.txt中。
快速排序有很多不同的算法来解决,在此我是用C++来编写这个程序的,根据快速排序的算法思想,很容易将此问题解决。还可以运用非递归的方法解决,但是我不熟练。
算法设计与分析实验报告,附已通过源码,供学习参考,共勉♪ 目录摘要如下: 1.问题描述 2.实验目的 3.实验原理 4.实验设计 (包括输入格式、算法、输出格式) 5.实验结果与分析 (除了截图外,实验结果还用...
经典的快速排序算法,使用分治法思想,使用C++的插入排序,使用算法课程的基础编程。