我有一个C ++程序将节点插入链表。节点包含一个我们称之为 data 的字符串,以及一个指向下一个节点的指针,我们称之为 next 。此外,头节点将被定义为 head 。
我不确定什么更有效率 - 1.将一串字符串插入我的列表,然后对其进行排序 2.或者在插入时对列表进行排序。
我认为这是后者,我想知道如何实现这样的目标。
我想知道实现这样一个函数的最简单方法。
答案 0 :(得分:4)
第一个解决方案:插入k个未排序的元素,只需将它们插入到开头,每个都是O(1)。和一种:O(nlogn)
在这些k元素之后。您获得O(nlogn+k)/k = O(n(logn/k))
的{{3}}时间。
第二个解决方案:将一个元素插入到列表中的顺序为O(n)
,因为您需要在列表中找到该位置。对于k个插入,它将为O(n*k)
,并按O(n*k/k) = O(n)
分摊。
因此第一个解决方案适用于logn < k
,第二个解决方案适用于logn > k
为了提高效率,您可能需要一个访问O(logn)中元素的排序数据结构,例如amortized [基本上是链表的变体,附加信息以便于访问]或{ {3}}
答案 1 :(得分:1)
我回答了类似的问题(99%相似:)) HERE
现在它的整数我想,对于字符串,您可以使用{C}提供的std::string compare
函数或strcmp
进行比较
根据我的意见并看到其他答案,您的应用程序(如果需要排序链表)在您插入时对数据进行排序会更好。
答案 2 :(得分:0)
我认为它实际上并没有什么区别,当你在插入时排序时,你会在插入上有O(n),因为你可能必须遍历整个列表才能找到正确的点插入。
但是,在将所有项目添加到列表后进行排序时,您还将至少有O(n)来移动列表中的项目。
答案 3 :(得分:0)
最简单的解决方案是使用C ++已经提供的内容 - std::list
和std::list::sort
:
#include <list>
#include <algorithm>
#include <iostream>
#include <string>
class Node {
public:
Node(const std::string& data) : Data(data) {
}
std::string Data;
};
bool NodeLess(const Node& n1, const Node& n2) {
return n1.Data < n2.Data;
}
void main() {
std::list<Node> l;
l.push_back(Node("d"));
l.push_back(Node("c"));
l.push_back(Node("a"));
l.push_back(Node("b"));
l.sort(NodeLess);
for (auto i = l.begin(); i != l.end(); ++i)
std::cout << i->Data.c_str() << " ";
}
如果您可以使用它(内存方式),您也可以使用std::vector
对项目进行预排序(通过std::sort
),然后再将它们插入链接列表中,这可能有点更快。
您也可以使用std::map
(甚至是std::set
)代替列表 - 它会在您插入项目时“自动排序”。
如果您仍想使用自己的列表,可以在其中实施begin
和end
,并使用std::stable_sort
。请注意,std::stable_sort
需要双向迭代器(与期望随机访问迭代器的std::sort
不同)。要在列表中实现双向迭代器,您需要使其双向链接,而不仅仅是单链接。