C++ 在复制透视时对整数进行分区

C++ Partition Integers when Pivot is Duplicated

本文关键字:整数 分区 复制 透视 C++      更新时间:2023-10-16

更新:

我最初是找到一种分区算法来对数组进行分区,作为快速排序算法的一部分。

例如像这样的数组:

[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 指出,我应该用 equal 更新一个条件,以便一个标准是"<",另一个是">=",这将使条件完整。

但是,分区

5, 3,

2, 4, 3, 1

基于枢轴 3,将是

而且三人不相邻。

真正的好东西出来了,三是否相邻其实并不重要。因为在仔细考虑快速排序算法之后,这个分区最终会使数组排序。

其中一个运算符更改为 <= ,而不是 <

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

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

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

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

尝试以下操作

#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