【问题标题】:Help with doubly Linked List in C++帮助 C++ 中的双向链表
【发布时间】:2011-08-30 01:14:45
【问题描述】:

所以我在解决这个问题时遇到了一些麻烦。 我创建了一个名为 dlist 的双向链表(其中包含一个链接节点帮助器类)。我有另一个名为 DeckOps 的类,它与链表一起使用。 dlist 已经包含 insertFront、removeFront、insertRear、removeRear 和打印函数的函数。目前,我将文件名传递给 DeckOps,然后读取文件,将 int 输入到列表的每个链接节点中(从后面放入以保持与文件中相同的顺序)。

现在我的问题是,我需要能够在列表中找到一个数字,所以我假设我需要一个查找功能。然后我需要能够选择数字以下的所有内容并将其与数字以上的所有内容交换。我认为单独的交换功能会很好吗? 我的主要问题是如何选择一个组并与另一个组交换。

谢谢

示例: 1 2 3 4 5 6 7 8 9 查找 6 查找 4 交换低于 6 的所有内容,以及高于 4 的所有内容 7 8 9 4 5 6 1 2 3 结果 编辑: 在写出这个例子时刚刚意识到程序需要知道我搜索的数字是靠近顶部还是底部。

不是在寻找解决方案,只是一些帮助。

【问题讨论】:

  • 这是作业吗?如果没有,你为什么不使用std::list<>
  • 我建议您先尝试编写您的 find 函数,并对其进行全面测试,然后再查看交换。我觉得你应该在来找我们之前尝试写一个 find()。
  • 可以使用列表来完成选择,而不是 int 存储指向列表节点的指针。但是你说的交换是什么意思?能举个例子吗?
  • 那么如果你的列表是[1, 2, 3, 4, 5, 6],而你选择了3,这会变成[6, 5, 4, 3, 2, 1](有效地反转列表)吗?还是你的意思是[4, 5, 6, 3, 2, 1]
  • 我的意思是如果我的列表包含 1 2 3 4 5 6 7 在交换发生在 5 以下的所有内容和 3 以上的所有内容之后,它将是 6 7 3 4 5 1 2 。 find 功能正在开发中,这真的不是问题。

标签: c++ pointers linked-list double


【解决方案1】:

只是古玩……有什么理由不使用 STL 容器类吗?

您真的需要重新发明轮子吗?您是否有您认为 STL 无法处理的需求?你认为你能比 STL 编码“更好”吗?您是否正在为不支持 STL 的嵌入式设备或晦涩难懂的处理器进行编码?

即使不是 STL,你考虑过 Boost++ 吗?

您可能在这里问错了问题......也许您应该问自己是否可以从其余的开发中抽出时间来重新发明轮子。

【讨论】:

  • 我可以使用 STL,但在过去的作业中已经有了我自己的双向链表。所以我认为创建自己的会比在 STL 中使用更灵活,除此之外我不太熟悉使用 stl::list 。我想我可能会因为操作而在使用 STL 列表时遇到问题。
  • +1 但是,我强烈建议您摆脱这种心态,原因如下:1)没有冒犯,但您的代码不太可能像 STL 那样好,编写和微调由一些真正的专业人士。 2) 也不灵活。 STL 真的很灵活,应该可以做任何你想做的事情。否则,你为什么要释放它?它应该是“所有的东西,所有的人”。 3)它需要比你的代码更少的测试(理论上不需要),并且应该更小更快。 4)您将获得比您自己的代码更多的对 STL 的支持(并且可以通过谷歌搜索答案,而不是提问)
  • 5) 你更有可能找到一份具有 STL 经验的工作(尽管编码列表往往会在面试中出现,但我不敢相信专业人士这样做会浪费钱)6)而且可能是最重要——你的时间很宝贵。不要浪费它重新发明轮子。花你时间做更多有趣的事情(如文档;-)
  • 你唯一真正为你赢得的课程编码的理由是学习 STL 可能需要太长时间。但是你只需要学习一次就可以永远使用它。它的设计易于学习。只值我的 2 美分
  • 是的,我现在正在使用 stl :)
【解决方案2】:

如果我正确解释了“交换”的含义,则需要实现list splicing。您可以将开头的范围移动到新列表,然后将其移回原始列表的末尾,或者您可以一次完成所有操作。后者只是稍微复杂一些,主要是在插入点不在要移动的范围内的前提条件方面。

Example with std::list:

int main() {
  std::list<int> L;
  for (int n = 0; n != 10; ++n) L.push_back(n);
  std::list<int>::iterator x = std::find(L.begin(), L.end(), 6);
  assert(x != L.end());  // We know this is true in this example.

  std::list<int> temp;
  temp.splice(temp.end(), L, L.begin(), x);
  temp.splice(temp.begin(), L, x);
  L.splice(L.end(), temp);

  std::copy(L.begin(), L.end(), std::ostream_iterator<int>(std::cout, ", "));

  return 0;
}

输出:

  7, 8, 9, 6, 0, 1, 2, 3, 4, 5, 
# ^-----^     ^--------------^
#   \... swapped with .../

【讨论】:

  • 但是如果我想在中间保留更多的数字而不仅仅是 6 怎么办?
  • @adsderek:那就这样做吧。设置您的迭代器范围并将它们移动到您喜欢的位置。 List::splice 接受一个迭代器或一个范围(我有上面的例子)。
  • 是的,我刚刚意识到我可以做到这一点,使用像你一样的迭代器 x 和迭代器 y,在另一个值。您提供的链接中的两个示例?现在如果我想切换两个号码怎么办?或者更确切地说,在列表中向上或向下移动元素多少次?
  • 我想回到这里寻求帮助,我遇到了上述问题,我不知道如何摆脱不知道我使用的数字是否在前面的想法或回来。假设我创建了一个列表 1 4 5 6 2 4 7 8 并将我的范围设置为 5 到 4,我怎么知道哪个在前面,哪个在后面?看到我需要外面的一切来改变地方,而中间的一切都保持不变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多