【问题标题】:Doubly Linked List fails to add or delete valid entries双向链表无法添加或删除有效条目
【发布时间】:2019-12-06 20:58:32
【问题描述】:

我已经运行过很多次了。我尝试修复我的 deleteNode() 和 addNode(),但它不起作用。输出显示它未能在我的列表中添加一些有效条目,从而导致无法删除这些有效条目。有人请帮我找出错误...我认为我的 isEmpty() 错误或 addNode 搞砸了。

// Add nodes and makes it work in any cases: backward/forward
bool LinkedList::addNode(int id, string str) {
    bool result = false;
    if (id >= 0 && !(idExists(id))) {
        Node *current = head;
        Node *temp = new Node;
        temp->data.data = str;
        temp->data.id = id;
        temp->forward = NULL;
        temp->back = NULL;

        // Kinds of adding cases
        if(head == NULL) {          // Check if list is empty
            addHead(temp, current);
            result = true;
        } else {
            while(temp->data.id > current->data.id && current->forward != NULL) {
                current = current->forward;
            }
            // Backward
            if(current->back == NULL) {
                if(temp->data.id > current->data.id) {
                    if(current->forward == NULL) {
                        addTail(temp, current);
                    } else {
                        addMiddle(temp, current);
                    }
                } else {
                    addHead(temp, current);
                }
                result = true;
            // Forward
            }else if(current->forward == NULL) {
                if (temp->data.id > current->data.id) {
                    addTail(temp, current);
                } else {
                    addMiddle(temp, current);
                }
                result = true;
            }else {
                if(temp->data.id > current->data.id) {
                    addMiddle(temp, current);
                    result = true;
                }
            }
        }
    }
    return result;
}

void LinkedList::addHead(Node *temp, Node *current) {
    if (head != NULL){
        temp->forward = current;
        current->back = temp;
        head = temp;
    } else {
        head = temp;
    }
}

void LinkedList::addMiddle(Node *temp, Node *current) {
    temp->forward = current;
    temp->back = current->back;
    current->back->forward = temp;
    current->back = temp;
}

void LinkedList::addTail(Node *temp, Node *current) {
    current->forward = temp;
    temp->back = current;
}

// Delete list
bool LinkedList::deleteNode(int id){
    bool result = false;
    if (idExists(id)) {
        Node *current = head;
        while (current->forward != NULL && current->data.id != id) {
            current = current->forward;
        }
        if (current->data.id == id && current->forward == NULL) {
            if (current->back == NULL) {        // Delete head
                delete current;
                head = NULL;
            } else {        // delete tail
                deleteTail(current);
            }
            result = true;
        } else if (current->data.id == id) {
            if (current->back == NULL)
                deleteHead(current);
            else            // delete middle
                deleteMiddle(current);
            result = true;
        }
    }
    return result;
}


// Helper delete functions
void LinkedList::deleteHead(Node *current) {
    head = current->forward;
    head->back = NULL;
    delete current;
}

void LinkedList::deleteMiddle(Node *current) {
        current->back->forward = current->forward;
        current->forward->back = current->back;
        delete current;
}

void LinkedList::deleteTail(Node *current) {
        current->back->forward = NULL;
        delete current;
}

bool LinkedList::getNode(int id, Data *data) {
    bool didGetNode = false;

    if (idExists(id)) {
        Node *current = head;
        while (current->forward != NULL && current->data.id != id) {
            current = current->forward;
        }
        data->id = current->data.id;
        data->data = current->data.data;
        didGetNode = true;
    }

    return didGetNode;
}

// Check whether or not the id exists
bool LinkedList::idExists(int id){
    bool exists = false;
    if (head != NULL){
        Node *current = head;
        while (current->forward != NULL && current->data.id != id) {
            current = current->forward;
        }
        if (current->data.id == id) {
            exists = true;
        }
    }
    return exists;
}

【问题讨论】:

  • 您的添加中真的需要这么多案例吗?你能解释一下(对自己)为什么你需要这些分支中的每一个,以及在什么情况下它们会被击中?
  • 请提供A Minimal, Complete, and Verifiable Example (MCVE)。可以编译以验证您的问题的内容以及提供DataNode 等定义的内容。
  • head 定义在哪里。
  • 从链表中插入不重复节点或按 id 删除节点的代码量大约是需要的 10 倍。先设计,然后代码。

标签: c++ data-structures linked-list doubly-linked-list


【解决方案1】:

您可能希望在要更改节点地址所包含内容的函数中传递指向指针 (**) 的指针或指向引用 (*&) 的指针。我希望这可以帮助您将其形象化。

例如:

struct Node { };

void setNull1(Node* temp)
{
    temp = nullptr;
}

void setNull2(Node** temp)
{
    (*temp) = nullptr;
}

void setNull3(Node*& temp)
{
    temp = nullptr;
}

int main()
{
    Node* tmp = new Node;

    setNull1(tmp);
    if (tmp == nullptr)
    {
        cout << "NULLPTR";
    } // tmp is not nullptr

    Node* tmp1 = new Node;
    setNull2(&tmp1);
    if (tmp1 == nullptr)
    {
        cout << "NULLPTR";
    } // tmp1 is nullptr

    Node* tmp2 = new Node;
    setNull3(tmp2);
    if (tmp2 == nullptr)
    {
        cout << "NULLPTR";
    } // tmp2 is nullptr
}

您还应该考虑写nullptr 而不是NULL

【讨论】:

  • 这如何适用于 OP 的 C++ 类 LinkedList,其中所有成员都已经拥有(并使用)对 head 成员的直接访问权限。
  • 出于某种原因,我认为他也在使用尾指针。但是了解上述概念将有助于 OP 简化他的代码。
猜你喜欢
  • 1970-01-01
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多