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

时间:2018-01-06 12:41:53

标签: c++ dictionary singly-linked-list

我正在使用带有递归插入功能的单链表制作一本字典,目前正在完成它的工作。 我有两个来自社区的请求:

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

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

  3. 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 个答案:

答案 0 :(得分:2)

  1. 我在这里发布的代码中没有看到任何内存泄漏。可能在其他地方(通常在析构函数或复制构造函数/赋值运算符中)。而且我不明白为什么你要将字典实现为链表。这似乎效率很低。
  2. 不需要指向列表中最后一个节点的指针。在这种情况下,它不会为你买任何东西,因为你无论如何都要遍历整个列表(找到匹配的密钥)。如果你不这样做,但你仍然希望在列表的末尾高效插入,那么尾指针是有意义的。
  3. 但是,您的代码可以简化很多:

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