按元素排序结构列表

时间:2015-05-12 09:48:09

标签: c++ list sorting struct

我有一个如下所示的结构:

struct Man 
{
  string surname;
  string name;
  char sex;
  int birth_year;
  int age;
  Man * next;
};

如何按姓氏按字母顺序对列表进行排序?

我知道如何使用数组冒泡排序,但无法使用list:/

处理

5 个答案:

答案 0 :(得分:1)

为了使std::list::sort工作,您需要做的就是重载您班级的<运算符。

在你的情况下,这看起来像这样

//n.b. untested code
bool operator< (const Man& other)
{
    toupper(this->surname) < toupper(other->surname);
}

你也可以调用sort的重载,它将comp函数作为参数。请参阅here

答案 1 :(得分:0)

只是建议,如果您要排序的唯一东西是姓氏,您可以尝试按姓氏的顺序添加此节点,然后您不需要再次排序,因为它&# 39;通过排序

制作

答案 2 :(得分:0)

使用std :: map&lt; string,Man&gt ;,将列表中的每个元素插入到此映射中,其中surname为键,Man的对象为value。 MAp的元素基于键进行排序,因此只需迭代映射以按排序顺序获取对象。

答案 3 :(得分:0)

  1. 您必须创建项目的std :: vector或std :: deque。
  2. 使用std :: sort。
  3. 示例:

    std::vector<Man*> people;
    Man* head = YOUR HEAD POINTER;
    // Create vector from your list
    while(head) { 
         people.push_back(head);
         head = head->next;  
    } 
    // sort vector
    std::sort(people.begin(),people.end(), [](const Man* m1, const Man* m2) {
        return m1->surname < m2->surname;
    });
    

答案 4 :(得分:0)

要对列表进行排序,您可以通过在现有列表的新列表中按顺序插入元素,从现有列表中构建新列表。

这是一个简化的例子。当然,您需要添加更多功能,例如将删除列表中所有节点的函数。

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <tuple>

struct Man 
{
    std::string surname;
    std::string name;
/*
    char sex;
    int birth_year;
    int age;
*/
    Man * next;
};

void push_front( Man * &head, const std::string &surname, const std::string &name )
{
    head = new Man { surname, name, head }; 
}

std::ostream & display( const Man *head, 
                        std::ostream &os = std::cout,
                        const char *delim = ", ")
{
    for ( const Man *tmp = head; tmp; tmp = tmp->next )
    {
        os << tmp->surname << ' ' << tmp->name << delim;
    }

    return os;
}

void sort( Man * &head )
{
    Man *new_head = nullptr;

    while ( head != nullptr )
    {
        Man *node = head;
        head = head->next;

        Man *prev = nullptr;
        for ( Man *tmp = new_head; 
              tmp && !
              ( std::tie( node->surname, node->name ) < std::tie( tmp->surname, tmp->name ) ); )
        {
            prev = tmp;
            tmp = tmp->next;
        }            

        if ( prev == nullptr )
        {
            node->next = new_head;
            new_head = node;
        }
        else
        {
            node->next = prev->next;
            prev->next = node;
        }
    }

    head = new_head;    
}

int main() 
{
    Man *head = nullptr;

    std::srand( ( unsigned int )std::time( nullptr ) );

    const size_t N = 10;

    for ( size_t i = 0; i < N; i++ )
    {
        push_front( head, 
                   std::string( 1, 'A' + std::rand() % ( 'Z' - 'A' + 1 ) ),
                   std::string( 1, 'A' + std::rand() % ( 'Z' - 'A' + 1 ) ) );
    }

    display( head ) << std::endl;

    sort( head );

    display( head ) << std::endl;

    return 0;
}

程序输出

Y P, D X, K J, R G, K J, X V, V I, X M, C K, A Y, 
A Y, C K, D X, K J, K J, R G, V I, X M, X V, Y P, 

您可以简单地比较两个节点的姓氏,而不是函数std::tie

考虑到将结构分成两部分会更好。例如

struct Man 
{
    std::string surname;
    std::string name;
    char sex;
    int birth_year;
    int age;
};

struct Node 
{
    Man person; 
    Node * next;
};