我可以使std :: list插入带有顺序的新元素吗?或者必须使用std :: sort?

时间:2016-03-07 09:51:42

标签: c++ stl

如果我想使用std::list并且插入列表的新元素将插入到与比较函数相关的正确位置 - 我可以这样做吗? 或者我必须在每次插入后使用std :: sort?

3 个答案:

答案 0 :(得分:9)

您可以使用:

  • std :: set如果你的元素是不可变的
  • std :: map如果你的元素有不可变的键,但应该有可变的值
  • std :: list并查找插入位置

std :: list with std :: lower_bound:

#include <algorithm>
#include <list>
#include <iostream>

    int main()
    {
        std::list<int> list;
        int values[] = { 7, 2, 5,3, 1, 6, 4};
        for(auto i : values)
            list.insert(std::lower_bound(list.begin(), list.end(), i), i);
        for(auto i : list)
            std::cout << i;
        std::cout << '\n';
    }

或者你可以填充整个std :: vector并在之后对它进行排序(注意:std :: sort不能在std :: list :: iterators上运行,它们不提供随机访问):

#include <algorithm>
#include <vector>
#include <iostream>

int main()
{
    std::vector<int> vector = { 7, 2, 5,3, 1, 6, 4};
    std::sort(vector.begin(), vector.end());
    for(auto i : vector)
        std::cout << i;
    std::cout << '\n';
}

注意:手动查找插入位置的列表的性能是最差的O(N²)。

答案 1 :(得分:1)

您有三种选择:

  1. 每次插入后排序
  2. 找到正确的索引并插入该索引
  3. 使用std::set(推荐)
  4. 第三个选项的示例:

    #include <iostream>
    #include <set>
    
    int main ()
    {
      int myints[] = {75,23,65,42,13};
      std::set<int> myset (myints,myints+5);
    
      std::cout << "myset contains:";
      for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
        std::cout << ' ' << *it;
    
      std::cout << '\n';
    
      return 0;
    }
    

    输出:

      

    myset包含:13 23 42 65 75

答案 2 :(得分:0)

是的,你可以。尝试以下内容,只需更改比较功能和类型即可。

#include <list>

inline
int compare(int& a, int&b) {
    return a - b;
}

template<typename T>
void insert_in_order(std::list<T>& my_list, T element, int (*compare)(T& a, T&b)) {
    auto begin = my_list.begin();
    auto end = my_list.end();
    while ( (begin != end) &&
        ( compare(*begin,element) < 0 )      ) {
        ++begin;
    }
    my_list.insert(begin, element);
}

int main() {
    std::list<int> my_list = { 5,3,2,1 };
    my_list.sort();                              //list == { 1,2,3,5}
    insert_in_order<int>(my_list, 4, &compare);  //list == {1,2,3,4,5}
}