Algorithms Quicksort 快速排序算法

来源:互联网 发布:天猫抢货软件 编辑:程序博客网 时间:2024/04/30 18:21
快速排序 

快速排序是一种不仅为了教学目的而且实际应用广泛的快速排序算法。平均来说,这个算法的复杂度是O(n log n),所以十分适合用来对大数据量进行排序。当你理解后,会觉得快速排序算法的思想十分简单,甚至你可以像写冒泡排序算法那样很快的写出快速排序的算法。

算法

快速排序采用了分治法的策略,下面描述了递归的步骤: 

  1. 选择一个中间值。我们选择一个中间元素作为中间值,这个中间元素可以是在待排序元素范围内的任何值,甚至即使它不存在于待排序数组中也可以。
  2. 分组. 我们使用以下方法来对元素进行重新排序:将所有小于中间值的数据排序到数组的左半边部分,所有大于中间值的数据放在数组的右半边部分。等于中间值的数据可以任意的放在数组左边或者右边。注意,这个待排序数组可能被分隔为两个不等长的部分。
  3. 对分隔后的两个数组进行排序。 用递归的方法对左右两个部分分别使用快速排序算法。(快速排序还有非递归的方法,更加高效)

分组算法详解

有两个索引 i 和 j ,在分组算法最初 i 指向待排序数组的第一个元素而 j 则指向数组的最后一个元素。向后移动索引 i ,并将其指向的元素与中间值比较直到出现大于中间值的元素,这时再向前移动索引 j ,并将其指向元素与中间值比较,直到出现小于中间值的元素。这时如果 i < j,就将 i 指向的元素与 j 指向的元素进行对调,并将 i 移动到下一个元素的位置,j 移动到前一个元素的位置。 最后当i = j 时整个分组过程结束。

分组后,所有在第 i 个元素之前的值都小于等于中间值,而在 第 j 个元素后的所有值都大于等于中间值。

示例. 对{1, 12, 5, 26, 7, 14, 3, 7, 2} 进行快速排序

注意,为了不让示例过长,我们在这里只是演示了递归的第一层的步骤,但是,实际 {1, 2, 5, 7, 3} and {14, 7, 26, 12} 会继续进行递归排序。

为什么这种排序方法可行?

在分组这一步,我们将待排序数组分隔为了两个部分,这样使左边部分中所有元素a都小于等于右边部分中的元素b,并且a 和 b 满足 a ≤ pivot ≤ b .在完成递归调用后左右两个部分的数组便都是有序排列的,考虑上边说的满足条件即可得出整个数组被排序的结论。

复杂度分析

平均地,快速排序算法的复杂度为 O(n log n ) ,但是证明过程就不在这里写了。在最坏的情况下,快速排序执行O(n2)次,但是应用在大多数实际的数据中都表现良好,并且效率一般优于其他复杂度为O(n log n)  的排序算法。

代码片段

分组算法自身是很重要的,因此它可以提出作为单独的功能点。C++中包含固定的函数用来执行快速排序,但是java中包含两个单独的函数分别用来分组和排序。 

JAVA

int partition(int arr[], int left, int right) {       int i = left, j = right;       int tmp;       int pivot = arr[(left + right) / 2];       while (i <= j) {             while (arr[i] < pivot)                   i++;             while (arr[j] > pivot)                   j--;             if (i <= j) {                   tmp = arr[i];                   arr[i] = arr[j];                   arr[j] = tmp;                   i++;                   j--;             }       };         return i; } void quickSort(int arr[], int left, int right) {       int index = partition(arr, left, right);       if (left < index - 1)             quickSort(arr, left, index - 1);       if (index < right)             quickSort(arr, index, right); }


C++

void quickSort(int arr[], int left, int right) {      int i = left, j = right;      int tmp;      int pivot = arr[(left + right) / 2];       /* partition */      while (i <= j) {            while (arr[i] < pivot)                  i++;            while (arr[j] > pivot)                  j--;            if (i <= j) {                  tmp = arr[i];                  arr[i] = arr[j];                  arr[j] = tmp;                  i++;                  j--;            }      };       /* recursion */      if (left < j)            quickSort(arr, left, j);      if (i < right)            quickSort(arr, i, right);}


Download link: full quicksort package. 完整的代码包下载

原文地址:http://www.algolist.net/Algorithms/Sorting/Quicksort

原创粉丝点击