如何改进单向链表插入函数 - C++

How to improve a singly linked list insert function - C++

本文关键字:函数 C++ 插入 链表 何改进      更新时间:2023-10-16

我正在使用带有递归插入函数的单向链表制作字典,该函数目前可以完成它的工作。我有两个来自社区的请求:

  1. 想知道是否有人可以查看我的代码并告诉我是否有任何内存泄漏,如果是,我应该如何删除它们。

  2. 通过查看其他列表,我看到它们都使用尾节点。为什么有必要这样做?

void dictionary::insert(Key k, Item i)
{
    if (head == nullptr)
    {
        head = new Node(k, i);
    }
    else insertRec(k, i, head);
}
void dictionary::insertRec(Key k, Item i, Node* current)
{
    Node* temp;
    if (current->key == k)
    {
        current->item = i;
    }
    else if(current->nextNode != nullptr)
    {
        insertRec(k, i, current->nextNode);
    }
    else if (current->nextNode == nullptr) {
        temp = new Node(k, i);
        current->nextNode = temp;
    }
}
  1. 我在这里发布的代码中没有看到任何内存泄漏。其他地方可能有一些(通常在析构函数或复制构造函数/赋值运算符中(。我不明白你为什么要将字典实现为链表。这似乎效率很低。
  2. 指向列表中最后一个节点的指针不是必需的。在这种情况下,它不会给你任何东西,因为你无论如何都要迭代整个列表(以找到匹配的键(。如果您不这样做,但仍然希望有效地插入列表末尾,那么尾部指针是有意义的。

但是,您的代码可以简化很多:

void dictionary::insert(Key k, Item i)
{
    for (Node **pp = &head; *pp; pp = &(*pp)->nextNode) {
        if ((*pp)->key == k) {
            (*pp)->item = i;
            return;
        }
    }
    *pp = new Node(k, i);
}

这是一个简单的循环,不需要递归,并且不需要对空指针进行两个单独的测试。


或者,如果必须使用递归:

void dictionary::insert(Key k, Item i)
{
    insertRec(head, k, i);
}
void dictionary::insertRec(Node *&current, k, i)
{
    if (!current) {
        current = new Node(k, i);
    } else if (current->key == k) {
        current->item = i;
    } else {
        insertRec(current->nextNode, k, i);
    }
}