所以我有一个链表程序半工作。我在某些方法上遇到了一些麻烦。...我记录的那些方法正在起作用,除了从末尾删除这很奇怪。

我正在将G ++作为我的编译器和C ++ 11在Mavericks上使用NetBeans
Here is a zip of all of the program files

这是我要制作的方法的列表:

//working
int size() const;
/kind of
void addToStart(Node *);
//working
void addToEnd(Node *);
//working
void printList();
//working
bool removeFromStart();
//kind of working
bool removeFromEnd();

//Still working on these
void removeNodeFromList(int);
void removeNodeFromList(string);


现在,我必须运行两次removeFromEnd()才能使其正常运行。意思是,我在程序开始时运行了一次,但它什么也不做,但是在以后的每一次中,它实际上都在执行删除操作。

对于addToStart(),如果我只运行一次,它将起作用。即:


我可以在程序开始时运行一次并打印出列表
我可以在使用addToEnd之后运行一次,但是如果再次尝试运行,并且尝试打印列表,它只会吐出我尝试添加的值。


如果我继续运行,addToEnd()可以完美找到,但是如果我执行以下操作,它将失败:

首先使用addToEnd()添加项目,然后使用addToStart()进行一次,然后尝试再次使用addToEnd()。当我打印出列表时,它只打印出两个对象,每个对象都是我尝试插入的最后一个值的副本。

void LinkedList::addToEnd(Node* ne)
{
    Node** q = &myHead;
    while (*q)
    {
        q = &(*q)->next;
    }

    *q = new Node(ne->itemName, ne->itemNo);
}

void LinkedList::printList()
{
    Node* p = myHead;
    while (p != NULL)
    {
        cout << p->itemNo << " " << p->itemName;
        cout << endl;
        p = p->next;
    }

    cout << endl << endl;
}

bool LinkedList::removeFromStart()
{
    if (myHead == NULL)
    {
        cout << "List is already empty";
    }
    else
    {
        myHead = myHead->next;
    }
}

bool LinkedList::removeFromEnd()
{
    if (myHead == NULL)
        return false;

    //Empty the list if there's only one element
    if (myHead->next == NULL)
    {
        delete myHead;
        myHead = NULL;
        myTail = NULL;
        return true;
    }

    // Find the last item in the list
    Node *temp = myHead;
    while (temp->next != myTail)
    {
        temp = temp->next;
    }

    delete myTail;
    temp->next = NULL;
    myTail = temp;
    return true;
}


此外,仍在尝试找出已删除的内容

void LinkedList::removeNodeFromList(int i) {


//Save the values
Node* p = myHead;
Node* temp = myHead->next;


    while (p) {

        if (p->itemNo == i) {

            p=temp;
        } else {
            p = p->next;
        }

    }

}

最佳答案

您有一个tail指针,那么为什么要遍历列表以查找结尾?另外,为什么要通过指针传递节点?

void LinkedList::addToEnd(Node ne)
{
    if (myHead == nullptr) // empty list
    {
        myHead = myTail = new Node(ne);
        myTail->next = nullptr;
    }
    else
    {
        myTail->next = new Node(ne); // assuming Node has an accessible copy constructor
        myTail = myTail->next;
    }
}


removeFromStart函数存在内存泄漏:

bool LinkedList::removeFromStart()
{
    if (myHead == nullptr)
    {
        cout << "List is already empty";
        return false;
    }


    Node* temp = myHead;
    myHead = myHead->next;
    if (myTail == temp) // if there is only 1 element in the list, head == tail
    {
        myTail = myhead;
    }
    delete temp;
    return true;
}


大概,removeFromEnd应该去掉尾巴:

bool LinkedList::removeFromEnd()
{
    if (myTail == nullptr)
        return false;

    // unless you have a doubly-linked list, loop to find 1 before the tail
    Node* temp = nullptr;
    for (temp = myHead; temp && temp->next != myTail; temp = temp->next);


    if (myHead == temp) // when there is only 1 element in the list, head == tail
    {
        delete temp->next;
        myHead = nullptr;
        myTail = nullptr;
    }
    else
    {
        delete temp->next;
        temp->next = nullptr;
        myTail = temp;
    }
    return true;
}


是的,您正在使用new(在addtoEnd函数中),因此必须使用delete(而不是free!)。

旁注:您可以使用std::unique_ptr更好地编写删除代码(实际上可以通过在任何地方使用它来总体上改善代码),这会使每行代码的长度大约为4行。我将其留给您实施。

关于c++ - 1次后,C++将节点添加到链表的开头失败。还有其他方法的麻烦,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20056107/

10-11 22:11