如何在不使用C ++ STL sort()的情况下对结构的向量进行排序

时间:2019-03-25 08:24:16

标签: c++

我正在尝试对包含结构的向量进行排序。在此程序中,我不想使用任何C ++标准模板库(STL),例如sort()。

我尝试了这段代码

for (auto k = GTSlist.begin(); k != GTSlist.end(); k++)
{ 
    for (auto l = GTSlist.begin()+1; l != GTSlist.end(); l++)    
    {
        if(k->owner > l->owner)
        {
            auto tmp = k->owner;
            k->owner = l->owner;
            l->owner = tmp;
        }
    }
}

打印矢量值

for (auto k = GTSlist.begin(); k != GTSlist.end(); k++) 
{
    cout << "\n print sorted vector k->owner =" << k->owner << "k->length =" << k->length ;
}

结构声明

Struct Basic802154GTSspec
{
    int owner;
    int start;
    int length;
}

结构声明

vector <Basic802154GTSspec> GTSlist;

在向量中插入值

// GTSlist.end()=5,length = 1,2,3,4,5 , owner= 5,1,4,2,3 
for (auto k = GTSlist.begin(); k != GTSlist.end(); k++) {
    Basic802154GTSspec newGTSspec;
    newGTSspec.length = value shown above;
    newGTSspec.owner = value shown above;
    GTSlist.push_back(newGTSspec); 
}

预期结果

print sorted vector k->owner  k->length= 1,2; 2,4; 3,5; 4,3; 5,1

实际结果

print sorted vector k->owner  k->length= 1,1; 5,2; 2,3; 4,4; 3,5

3 个答案:

答案 0 :(得分:3)

此代码是错误的:

if(k->owner > l->owner)
{
     auto tmp = k->owner;
     k->owner = l->owner;
     l->owner = tmp;
}

执行此操作:

if (k->owner > l->owner)
{
    auto tmp = *k;
    *k = *l;
    *l = tmp;
}

而且,因为我认为auto在这里掩盖了一个重要的细节:

if (k->owner > l->owner)
{
    Basic802154GTSspec tmp = *k;
    *k = *l;
    *l = tmp;
}

最后,您应该使用::std::iter_swap作为其他建议的答案进行调查。这是STL的便利功能,并且是::std::swap的伴侣(您也可以在这里使用它)。使用它的主要优点是,您稍微简化了代码,消除了出错的机会,并且将在可能的地方使用移动语义,这在许多情况下会更有效(尽管可能不是您的特定情况) )。

如果您不知道什么是移动语义,请不要担心。这是高级C ++想法的中间,您可以不用担心初学者。

说了这么多,不使用STL算法是愚蠢的。您的排序实现是我所知道的第二种较差的排序算法(冒泡排序)。我所知道的唯一一个更糟糕的情况是,它会反复随机地整理数组,直到偶然地以排序顺序结束数组。

答案 1 :(得分:0)

for (auto k = GTSlist.begin(); k != GTSlist.end(); k++)
{ 
    for (auto l = GTSlist.begin()+1; l != GTSlist.end(); l++)    
    {
        if(k->owner > l->owner)
        {
            auto tmp = k->owner;
            k->owner = l->owner;
            l->owner = tmp;
        }
    }
}

您只交换“所有者”,而您需要交换所有结构内容,而且 l 不依赖于 k ,可以(我想您不想也可以使用std :: swap)

for (vector <Basic802154GTSspec>::iterator k = GTSlist.begin(); k != GTSlist.end(); k++)
{ 
    for (vector <Basic802154GTSspec>::iterator l = k+1; l != GTSlist.end(); l++)    
    {
        if(k->owner > l->owner)
        {
            auto tmp = *k;
            *k = *l
            *l = tmp;
        }
    }
}

您在

中还遇到了灾难性问题
for (auto k = GTSlist.begin(); k != GTSlist.end(); k++) {
    Basic802154GTSspec newGTSspec;
    newGTSspec.length = value shown above;
    newGTSspec.owner = value shown above;
    GTSlist.push_back(newGTSspec); 
}

如果 GTSlist 在到达 for 时不为空,则您将永不停止并在 GTSlist

中不断添加新元素

答案 2 :(得分:0)

您可能不想使用用户iter_swap,而您的功能变得非常简单:

template <typename ForwardIterator>
void bubble_sort( ForwardIterator first, ForwardIterator last )
{
    for ( ForwardIterator sorted = first; first != last; last = sorted )
    {
        sorted = first;
        for ( ForwardIterator current = first, prev = first; ++current != last; ++prev )
        {
            if ( *current < *prev )
            {
                std::iter_swap( current, prev );
                sorted = current;
            }
        }
    }
}