这篇文章介绍 一个非常流行并且高效的排序算法: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);
}
分享到:
相关推荐
同时,由于快速排序的平均性能优秀,且在大多数情况下都能保持较好的效率,因此它是实际应用中最常用的排序算法之一。 在实际编程实现快速排序时,需要注意以下几点: - **避免最坏情况**:可以通过随机化主元的...
本实验旨在通过对两种经典排序算法——快速排序和归并排序的研究与实现,深入理解它们的基本原理、时间复杂度,并通过编程实践比较这两种算法在不同数据规模下的性能表现。 #### 二、快速排序 **1. 基本思想** ...
分治法的经典应用包括:快速排序、归并排序、大整数乘法(Karatsuba算法)、Strassen矩阵乘法、汉诺塔问题等。 **三分法详解:** 三分法是分治法的一个变种,主要应用于查找问题,例如在有序数组中查找特定元素。...
本篇文章主要探讨了如何在VC++环境中利用多线程技术来实现三种经典的排序算法:冒泡排序、快速排序和归并排序,并对它们的性能进行了比较。 首先,冒泡排序是一种简单的排序算法,它重复地遍历待排序的数列,一次...
快速排序,使用分治算法,绝对AC,使用C++算法,没有使用sort,时间复杂度O(n logn)
总的来说,快速排序是一种非常重要的排序算法,它充分利用了分治法的优势,通过巧妙的分区策略和递归实现,使得在大多数情况下都能获得高效的表现。理解和掌握快速排序对于提升编程能力,特别是在处理数据处理和算法...
本主题将详细探讨四种常见的排序算法:选择排序、插入排序、快速排序以及冒泡排序,它们都是用C语言实现的。以下是这些排序算法的详细解析: 1. **选择排序(Selection Sort)** - 选择排序是一种简单直观的排序...
用分治算法的思想,加上递归 实现快速排序
包括所有算法分析设计的实验(java快速排序。归并排序,分治算法,回溯算法,n后问题)
**希尔排序、快速排序与归并排序:NlogN经典排序算法详解** 排序算法是计算机科学中的基础且重要的一部分,尤其是在处理大量数据时,高效排序能够显著提升程序性能。本资料包聚焦于三类时间复杂度为O(nlogn)的经典...
快速排序(Quick Sort)是一种分治思想的排序算法,它的基本思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后再分别对这两部分记录继续进行排序,以达到...
快速排序是一种高效的排序算法,由英国计算机科学家C.A.R. Hoare在1960年提出。它基于分治法(Divide and Conquer)的思想,是计算机科学中最为广泛使用的排序算法之一。分治法的基本策略是将一个复杂的问题分解成两...
本主题将深入探讨四种常见的排序算法:归并排序、快速排序以及与链表相关的排序方法。 首先,我们来讨论归并排序(Merge Sort)。这是一种基于分治策略的排序算法。归并排序将大问题分解为小问题,然后逐步合并这些...
快速排序利用分治法将数组分为两部分,分别对它们进行排序,然后合并结果。归并排序则是将数组一分为二,分别排序后合并。 - **搜索问题**:如二分查找。在有序数组中寻找目标值,每次查找都使搜索范围减半,直到...
归并排序也是基于分治法的排序算法,但与快速排序不同的是,它不是通过交换元素来实现排序,而是通过合并已排序的子数组来达到目的。归并排序的过程如下: 1. **分割**:将原始数组分为两个或更多个子数组,每个子...
总的来说,快速排序和折半查找是计算机科学中不可或缺的算法,通过递归和分治策略,可以在Java中高效地实现这些算法,并结合界面设计,为用户提供直观的交互体验。在实际项目中,理解和掌握这些算法有助于优化数据...
合并排序算法、快速排序算法和递归分治是计算机科学中的基础概念,它们在数据处理和算法设计中占据着重要地位。以下是对这些知识点的详细解释: **合并排序算法(Merge Sort)** 合并排序是一种基于分治策略的排序...
- **排序算法**:快速排序、归并排序等都是基于分治策略的经典算法。 - **数值计算**:如多项式乘法中的快速傅里叶变换(FFT),以及矩阵乘法中的Strassen算法。 - **图形处理**:如凸包问题中的Graham扫描算法,...