我想将数组的元素插入到链接列表中。以下是我正在使用的一段代码:
{{1}}
这里randArray [i]包含100000个元素。
现在我希望这个过程能够更快地执行。目前,50000个元素需要13秒。
有人可以帮帮忙吗?
答案 0 :(得分:3)
您现在每次插入新节点时都在寻找最后一个节点...但是您已经知道最后一个节点的位置,因为您刚刚在最后一次迭代中插入了它 - 如果您还没有#39扔掉那些信息。只需将指针存储在一个不会在迭代结束时被销毁的变量中。另一种方式 - 对于单链表来说更典型 - 只是插入列表的前面。如果您希望元素的顺序与数组中的顺序相同,则以相反的顺序迭代数组。
去掉线性搜索结束会将算法的运行时复杂度从O(n ^ 2)降低到O(n)。
另一个对性能影响较小但会使代码更简单的优化:使用insert-in-front-only方法并使用sentinel节点实现列表。这样你就不需要在每次迭代中都有一个分支。也就是说,由于易于预测,该分支可能影响不大。通过在循环外部移动测试,您也可以使用remember-last-node方法摆脱分支,但这不会简化您的代码。
编辑:毕竟不需要Sentinel节点,即使它确实简化了一些其他列表算法。我很无聊,所以我实现了只插入前端的方法:
Node* head = nullptr;
for (size_t i = MAXSIZE; i --> 0;) {
Node* n = new Node();
n->SetData(randArray[i]);
n->SetIndex(i); // †
n->SetNext(head);
head = n;
}
†如果您确实要将索引存储在节点中,可能需要重新考虑。当节点稍后插入或从尾部以外的任何其他位置移除时更新它将会非常慢。
答案 1 :(得分:2)
应用user2079303建议,
你应该有类似的东西:
Node *p = start;
for (int i = 0; i<MAXSIZE; i++)
{
Node* n1 = new Node();
n1->SetData(randArray[i]);
n1->SetIndex(i);
n1->SetNext(NULL);
//checks if NULL
if (start == NULL)
{
start = n1;
start->SetNext(NULL);
p = start;
}
else
{
//inserts the values to the end of the node
p->SetNext(n1);
p = p->GetNext();
}
}
答案 2 :(得分:1)
这是一个示例,以防您想要实际的追加操作。 get和set函数阻止你使用指向指针的指针,但这只需要一个if语句来检查空列表。
Node* tail; // pointer to last node on list (if start != NULL)
for (int i = 0; i<MAXSIZE; i++)
{
Node* n1 = new Node();
n1->SetData(randArray[i]);
n1->SetIndex(i);
//checks if empty list
if (start == NULL) {
start = n1;
tail = n1;
}
else {
tail->SetNext(n1);
tail = tail->GetNext();
}
}
tail->SetNext(NULL);
答案 3 :(得分:0)
如果你想在最后一个位置添加你只需要保留最后一个节点的引用,你就不需要每次都在链表上进行迭代,它会在下一个节点上添加节点。如: -
Node* head ;
Node* last= null;
for (int i = 0; i < MAXSIZE; i++) {
Node* n1 = new Node();
n1->SetData(randArray[i]);
n1->SetIndex(i);
n1->SetNext(null);
if(last != null){
last->SetNext(n1);
}else{
head = n1;
}
last = n;
}