数据透视重复时C ++分区整数

时间:2014-11-15 05:05:18

标签: c++ quicksort partitioning

更新

我最初是为分区数组找到一个分区算法,作为快速排序算法的一部分。

如数组:

  

[5,3,2,4,3,1]

基于3的枢轴,到

  

[小于3 || 3,3,大于3]

最后发现没有必要得到上面的分区,下面的结果也会快速排序:

  

[小于3 || 3,大于或等于3]

这意味着3不需要彼此相邻。

我的代码在下面(

int partition(std::vector<int>& v, int pivot)
{
  int left = 0;
  int right = v.size()-1;
  while (left != right)
  {
    while (v[left] < pivot) ++left;
    while (pivot < v[right]) --right;
    swap(v[left], v[right]);
  }
  return left;
}

Ben注意到我应该更新一个标准,因此一个标准是'&lt;'另一个是'&gt; =',这将使条件完成。

然而,

的分区
  

5,3,2,4,3,1

基于枢轴3,将是

  

&LT; 3 || 3,4,3,5

并且三个人不相邻。

真正的好事出来了,三个是否相邻无关紧要。因为在仔细考虑快速排序算法之后,这个分区最终会使数组排序。

2 个答案:

答案 0 :(得分:1)

将您的某个运营商更改为<=,而不是<

while (v[left] < pivot) ++left;
while (pivot <= v[right]) --right;

这样,每个数字都符合两个标准之一。要么它小于枢轴,它向左移动,或者枢轴小于或等于它,它向右移动。没有中间立场。

对于广义比较仿函数,您可以简单地交换参数并反转结果以获得相同的效果:

while ( compare(v[left], pivot) ) ++left;
while ( !compare(v[right], pivot) ) --right;

答案 1 :(得分:1)

尝试以下

#include <iostream>
#include <vector>
#include <utility>

std::vector<int>::size_type partition( std::vector<int> &v, int pivot )
{
    std::vector<int>::size_type i = 0, j = v.size();

    while ( i != j )
    {
        while ( i != j && v[i] < pivot ) i++;
        while ( i != j && !( v[--j] < pivot ) );
        if ( i != j ) std::swap( v[i++], v[j] );
    }

    return i;
}

int main() 
{
    std::vector<int> v = { 1, 4, 3, 5, 4, 6 };

    std::vector<int>::size_type n = partition( v, 4 );

    for ( std::vector<int>::size_type i = 0; i < n; i++ )
    {
        std::cout << v[i] << ' ';
    }
    std::cout << std::endl;

    for ( std::vector<int>::size_type i = n; i < v.size(); i++ )
    {
        std::cout << v[i] << ' ';
    }
    std::cout << std::endl;

    return 0;
}

输出

1 3 
4 5 4 6