其他分享
首页 > 其他分享> > c – 提高从数组中将元素插入链接列表的性能

c – 提高从数组中将元素插入链接列表的性能

作者:互联网

我想将数组的元素插入到链接列表中.以下是我正在使用的代码段:

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);
        }
        else {
            //inserts the values to the end of the node
            Node *p = start;
            while (p->GetNext() != NULL) {
                p = p->GetNext();
            }
            p->SetNext(n1);
        }
    }

这里randArray [i]包含100000个元素.

现在我希望这个过程能够更快地执行.目前,50000个元素需要13秒.

有人可以帮帮忙吗?

解决方法:

您现在正在寻找每次插入新节点时的最后一个节点…但您已经知道最后一个节点的位置,因为您刚刚在最后一次迭代中插入它 – 如果您还没有抛出该信息.只需保存一个指向它的指针,该指针存储在迭代结束时未被销毁的变量中.另一种方式 – 对于单链表来说更典型 – 只是插入列表的前面.如果您希望元素的顺序与数组中的顺序相同,则以相反的顺序迭代数组.

摆脱线性搜索结束会将算法的运行时复杂度从O(n ^ 2)降低到O(n).

另一个对性能影响较小的优化,但会使您的代码更简单:使用insert-in-front-only方法并使用sentinel节点实现列表.这样,您在每次迭代中都不需要分支.也就是说,由于易于预测,该分支可能影响不大.通过在循环外部移动测试,您也可以使用remember-last-node方法摆脱分支,但这不会简化您的代码.

编辑:毕竟不需要sentinel节点,即使它确实简化了一些其他列表算法.我很无聊,所以我实现了insert-in-front-only方法:

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;
}

†如果您确实要将索引存储在节点中,可能需要重新考虑.当节点稍后插入或从尾部以外的任何其他位置移除时更新它将会非常慢.

标签:c,arrays,data-structures,linked-list,singly-linked-list
来源: https://codeday.me/bug/20190824/1707304.html