Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多个列表中的项目_C++_Data Structures_Linked List - Fatal编程技术网

C++ 多个列表中的项目

C++ 多个列表中的项目,c++,data-structures,linked-list,C++,Data Structures,Linked List,所以我有一些遗留代码,我希望使用更现代的技术。但我担心,考虑到事物的设计方式,这是一个不可选择的选择。核心问题是,通常一个节点一次位于多个列表中。大概是这样的: struct T { T *next_1; T *prev_1; T *next_2; T *prev_2; int value; }; using namespace boost::intrusive; struct tag1; struct tag2; typedef list_base

所以我有一些遗留代码,我希望使用更现代的技术。但我担心,考虑到事物的设计方式,这是一个不可选择的选择。核心问题是,通常一个节点一次位于多个列表中。大概是这样的:

struct T {
    T *next_1;
    T *prev_1;
    T *next_2;
    T *prev_2;
    int value;
};
using namespace boost::intrusive;

struct tag1; struct tag2;

typedef list_base_hook< tag<tag1> > base1;
typedef list_base_hook< tag<tag2> > base2;

class T: public base1, public base2
{
    int value;
}

list<T, base_hook<base1> > list1;
list<T, base_hook<base2> > list2;

// constant time to get iterator of a T item:
where_in_list1 = list1.iterator_to(item);
where_in_list2 = list2.iterator_to(item);

// once you have iterators, you can remove in contant time, etc, etc.
这使得内核可以分配一个
T
类型的对象,并将其插入到两个双链接列表中,既美观又高效

显然,我可以只使用2个std::list,然后将对象插入其中……但有一件事效率要低得多……删除

代码通常需要“销毁”类型为
T
的对象,这包括从所有列表中删除元素。这很好,因为给定一个
T*
代码可以将该对象从其存在的所有列表中删除。对于像
std::list
这样的东西,我需要搜索对象以获得迭代器,然后删除它(我不能只传递迭代器,因为它在多个列表中)


有没有一个很好的c++-ish解决方案,或者手动滚动的方式是最好的方式?我觉得手动滚动方式就是答案,但我想我会问。

我认为正确的答案取决于此应用程序的性能关键程度。它是否在一个内部循环中,可能会使程序产生用户可感知的运行时差异


有一种方法可以通过创建从一些STL容器派生的类来创建这类功能,但这对您来说可能并不值得。冒着听起来令人厌烦的风险,我认为这可能是一个过早优化的例子。

我认为正确的答案取决于此应用程序的性能关键程度。它是否在一个内部循环中,可能会使程序产生用户可感知的运行时差异


有一种方法可以通过创建从一些STL容器派生的类来创建这类功能,但这对您来说可能并不值得。冒着听起来令人厌烦的风险,我认为这可能是一个过早优化的例子。

听起来你在谈论一些可以通过应用图论来解决的问题。因此,Boost Graph Library可能会提供一些解决方案。

听起来你在谈论一些可以通过应用图论来解决的问题。因此,Boost图形库可能会提供一些解决方案。

您确实可以使用std::list,而不是管理自己的下一个/上一个指针。为了解决remove的性能问题,可以将迭代器存储到对象本身(元素可以存储在其中的每个std::list都有一个成员)


您可以扩展它来在类中存储一个向量或迭代器数组(如果您不知道元素存储在其中的列表数量)。

您确实可以使用std::list来代替管理自己的下一个/上一个指针。为了解决remove的性能问题,可以将迭代器存储到对象本身(元素可以存储在其中的每个std::list都有一个成员)

您可以将其扩展为在类中存储一个向量或迭代器数组(以防您不知道元素存储在其中的列表的数量)。

就是您所追求的。它将删除列表中与您传入的值相同的所有对象

因此:

列表列表一、列表二;
//事情会被添加到列表中。
不要动东西;
列表一。移除(要移除的内容);
清单2.移除(要移除的内容);
我还建议将列表节点转换为类;这样C++会为你保管好内存。
class MyThing {
  public:
  int value;
  // Any other values associated with T
};

list<MyClass> listOne, listTwo; // can add and remove MyClass objects w/o worrying about destroying anything.
类神话{
公众:
int值;
//与T相关的任何其他值
};
列出列表一,列表二;//可以添加和删除MyClass对象,而不用担心破坏任何东西。
您甚至可以使用add/remove方法将这两个列表封装到它们自己的类中。然后,当您想要移除一个对象时,只需调用一个方法

class TwoLists {
  private:
  list<MyClass> listOne, listTwo;

  // ...

  public:
  void remove(const MyClass& thing) {
    listOne.remove(thing);
    listTwo.remove(thing);
  }
};
类列表{
私人:
列表一,列表二;
// ...
公众:
无效删除(const MyClass&thing){
移除(事物);
清单二:移走(东西);
}
};
就是你想要的。它将删除列表中与您传入的值相同的所有对象

因此:

列表列表一、列表二;
//事情会被添加到列表中。
不要动东西;
列表一。移除(要移除的内容);
清单2.移除(要移除的内容);
我还建议将列表节点转换为类;这样C++会为你保管好内存。
class MyThing {
  public:
  int value;
  // Any other values associated with T
};

list<MyClass> listOne, listTwo; // can add and remove MyClass objects w/o worrying about destroying anything.
类神话{
公众:
int值;
//与T相关的任何其他值
};
列出列表一,列表二;//可以添加和删除MyClass对象,而不用担心破坏任何东西。
您甚至可以使用add/remove方法将这两个列表封装到它们自己的类中。然后,当您想要移除一个对象时,只需调用一个方法

class TwoLists {
  private:
  list<MyClass> listOne, listTwo;

  // ...

  public:
  void remove(const MyClass& thing) {
    listOne.remove(thing);
    listTwo.remove(thing);
  }
};
类列表{
私人:
列表一,列表二;
// ...
公众:
无效删除(const MyClass&thing){
移除(事物);
清单二:移走(东西);
}
};

要回答的问题是为什么这个C结构首先存在。在你知道这个功能是什么之前,你不能重新实现C++中的功能。有几个问题可以帮助你回答:

  • 为什么要列出清单?数据是否需要按顺序排列?订单有什么意义吗?应用程序是否需要有序遍历
  • 为什么是两个集装箱?容器中的成员身份是否表示元素的某种属性
  • 为什么要特别使用双链接列表?O(1)的插入和删除是否重要?反向迭代重要吗
  • 对其中一些或所有问题的答案可能是,“没有真正的原因,这只是他们如何实施的”。如果是这样,您可以用非侵入式C++容器解决方案来取代这种侵入式C指针混乱,可能包含SypDypPTR而不是PTRs。