有三个不同整数的排序数组,只经过一次传递

sorted array with three different integers with only one pass

本文关键字:经过 一次 数组 三个 整数 排序      更新时间:2023-10-16

是否有可能对三个整数的数组进行排序,仅对数组进行一次传递?

:

int array[]={1,2,2,2,3,1,1,2,2,1,3}

,你被告知只有数字1、2、3

:

int array[]={1,1,1,1,2,2,2,2,2,3,3}

和不允许额外的空间

Tnx !

一行,不加空格:

第一个指针:表示数组2的起始点。

last指针:表示数组中第3的起始点。

如果找到1,将其与第一个指针交换。

如果你找到一个2,把它留在那里。

如果找到一个3,将它与最后一个指针交换。

排练:

{1,2,2,2,3,1,1,2,2,1,3} cur=1, first=1, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=2, first=2, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=3, first=2, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=4, first=2, last=10
{1,2,2,2,3,1,1,2,2,1,3} cur=5, first=2, last=10
{1,2,2,2,1,1,1,2,2,3,3} cur=5, first=2, last=9
{1,1,2,2,2,1,1,2,2,3,3} cur=5, first=3, last=9
{1,1,1,2,2,2,1,2,2,3,3} cur=6, first=4, last=9
{1,1,1,1,2,2,2,2,2,3,3} ...

时间:0 (n)(一次)

空间:O (1)

是的,使用计数排序。基本上,您遍历输入数组一次,并计算每个值出现的频率。之后,只需为每个bucket发出适当数量的值。

编辑:计数,不是桶排序。

这是一个直接的方法(不需要测试)

#include <iostream>
#include <algorithm>
#include <iterator>
void sort( int *first, int *last )
{
    for ( int *current = first; current != last; )
    {
        if ( *current == 1 )
        {
            if ( current == first )
            {
                ++current;
            }
            else
            {
                std::swap( *current, *first );
            }
            ++first;
        }
        if ( *current == 3 )
        {
            --last;
            if ( *current != *last ) std::swap( *current, *last );
        }
        if ( *current == 2 ) ++current;
    }
}
int main() 
{
    int a[] = { 1, 2, 2, 2, 3, 1, 1, 2, 2, 1, 3 };
    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;
    sort( std::begin( a ), std::end( a ) );
    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;
    return 0;
}

输出为

1 2 2 2 3 1 1 2 2 1 3 
1 1 1 1 2 2 2 2 2 3 3 

这是e.w. Dijkstra在70年代早期描述的荷兰国旗问题的简单线性解决方案。它有时被用作快速排序的分区方法。

#include <iostream>
template <typename BidIt, typename T>
void dnf_partition(BidIt first, BidIt last, const T &pivot)
{
    for (BidIt next = first; next != last;) {
        if (*next < pivot) {
            std::iter_swap(first++, next++);
        } else if (pivot < *next) {
            std::iter_swap(next, --last);
        } else {
            ++next;
        }
    }
}
int main()
{
    int array[] = { 1, 2, 2, 2, 3, 1, 1, 2, 2, 1, 3 };
    for (int n : array) std::cout << n << ' ';
    std::cout << 'n';
    dnf_partition(std::begin(array), std::end(array), 2);
    for (int n : array) std::cout << n << ' ';
    std::cout << 'n';
}

ideone.com现场演示

是。对于计数排序,

int array[]={1,2,2,2,3,1,1,2,2,1,3};
int count[]={0,0,0};
int i = 0;
while (array[i] != '') {
  count[array[i] - 1]++;
  i++;
}
for (i = 0; i < count[0]; i++) {
  printf("%i", 1);
  printf(",");
}
for (i = 0; i < count[1]; i++) {
  printf("%i", 2);
  printf(",");
}
for (i = 0; i < count[2]; i++) {
  printf("%i", 3);
  if (i + 1 < count[2]) {
    printf(",");
  }
}
printf("n");

编辑

不允许有额外的空间

则没有。这是不可能的