是否有真正的C ++快速排序算法?

时间:2015-09-18 15:05:14

标签: c++ arrays algorithm sorting

编辑:OP的混乱resulted from assuming the pivot had fixed position。它实际上取决于有多少元素< =它。如果其中一个示例选择7作为枢轴元素,最终将其交换到更高的索引,并使用来自位置中不同元素的7完成第一次传递,则无济于事枢纽开始了。

自从我了解了CS中的快速排序然后开始将其应用于代码之后,我一直在努力解决代码执行真正的快速排序算法的概念。快速排序的想法很简单:选择原始数组的一个数据透视表,并从数组中的所有其他数字排序到该数据透视图的左侧或右侧。然后通过递归调用通过相同的方法对每个子数组(枢轴和枢轴右侧的项)进行排序,直到整个数组都被排序。

在实践中,我遇到的每种语言似乎都有相同的公认代码来完成此任务。它看起来像这样(来自http://www.algolist.net/Algorithms/Sorting/Quicksort):

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);
}

但是,正如您从网站自己的视觉中看到的那样,当第一个分区停止时,“3”仍位于所选“7”枢轴的右侧。在测试其他阵列时我也观察到了这一点。对于[6,5,1,3,8,4,7,2,2],第一个轴是8.在第一个分区之后,8一直到9的右边,直到最后一个递归调用。有没有人注意过这个?

1 个答案:

答案 0 :(得分:10)

  

但是,正如您从网站自己的视觉中看到的那样,当第一个分区停止时,“3”仍位于所选“7”枢轴的右侧

分区会移动算法所提供的left <= 7 <= right所有内容:

1 2 5 7 3 | 14 7 26 12

所选的枢轴不是数组元素 7,而是 7。

将数据透视为,而不是数组的元素。这就是理论所说的,你所链接的网站也是这样说的:

  

选择一个支点值。我们将中间元素的值作为透视值,但它可以是任何值,即在数组中不存在时,它在排序值的范围内。

选择元素的值只是一种方便。如果你替换“|”以上7,算法符合理论。

Quicksort 可以也可以实现为left | pivot | right,例如,请参阅Wikipedia上的第一个伪代码。它不会 ,而left <= pivot | pivot | right >= pivotleft <= pivot | right >= pivot的子集。所以如果你先做第一个,你实际上也会做第二个。