如何从链表中删除节点?

时间:2017-05-16 16:14:30

标签: c++ list linked-list

将整数添加到列表工作正常,但删除和打印有问题。

我对调试器不友好,但我发现节点指针'first'有错误。其值为-17891602。我不知道发生了什么......

#include <iostream>
using namespace std;

class nodeList;

class node {
    friend class nodeList;
private:
    int data;
    node* link;
public:
    node() { //constructor
        data = 0;
        link = NULL;
    }
    node(int d) { //constructor
        data = d;
        link = NULL;
    }
    node(int d, node* l){ //constructor
        data = d;
        link = l;
    }
};

class nodeList {
private:
    node* first;
    int num = 0;
    node* nt;
public:
    nodeList() {
        first = new node();
    }
    node* end(node* t){ //return pointer of last element
        t = first;
        for (int i = 0; i < num; i++){
            t = t->link;
        }
        return t;
    }
    void add(int a){ //add 'a' at the end of the list
        node* x = new node(a);
        node* y = this->end(nt);
        y->link = x;
        num++;
    }

    void del(int n){ //n : data of element that you want to delete from list
        node* temp = first;
        node* pretemp = NULL;
        node* x;
        int i;
        for (i = 0; i <= this->num; i++){ //loop to find 'n'
            pretemp = temp;
            temp = temp->link;
            if (n == temp->data){
                break;
            }
        }
        temp = first;
        for (int j = 0; j<i; j++){ //i : where 'n' is,
            temp = temp->link;
        }
        x = temp->link;
        pretemp->link = x;
        delete temp;
        num--;
    }
    void printList(){
        node* temp = first;
        temp = temp->link;
        for (int i = 0; i<this->num; i++){
            cout << temp->data << endl;
            temp = temp->link;
        }
    }
};

int main(){
    nodeList *l = new nodeList();
    int a;
    int select;
    while (1){
        cout << "1. ADD  2. DELETE  3. PRINT" << endl;
        cin >> select;

        if (select == 1){
            cout << "Enter an integer: ";
            cin >> a;
            if (cin.fail()) {
                cout << "Wrong input" << endl;
                break;
            }
            l->add(a);
            l->printList();
        }

        if (select == 2){
            cout << "Enter the data of the element you want to delete: ";
            cin >> a;
            if (cin.fail()) {
                cout << "Wrong input" << endl;
                break;
            }
            l->del(a);
            l->printList();
        }

        if (select == 3){
            l->printList();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您的del函数会删除pretemp节点(在您需要删除的节点之前的节点)。

以下是可能的解决方法:

//n : data of element that you want to delete from list
void del(int n)
{
    //loop to find 'n'
    for (node *tmp = first; tmp->link; tmp = tmp->link)
    {
        if (n == tmp->link->data)
        {
            node *x = tmp->link;
            tmp->link = tmp->link->link;
            delete x;
            num--;
            break;
        }
    }
}

此外,您的del是否应该使用data == n删除所有节点?

答案 1 :(得分:0)

这些功能有点复杂。这是一个更简单的想法:

void del(int n){
    node* pretemp = first, *temp = first->link;
    if(pretemp->data == n) { //handle the deleting of the first node
            first = first->link;
            delete pretemp;
            return;
    }
    while(temp != NULL && temp->data != n) { //find the node with the data member "n"
            pretemp = temp;
            temp = temp->link;
    }
    if(temp != NULL) { //if you found the node, delete it
            pretemp->link = temp->link;
            delete temp;
    }
    --num;
 }

答案 2 :(得分:0)

您的代码有点过于复杂,无法满足需要。

尝试更像这样的东西:

#include <iostream>
#include <limits>

using namespace std;

class nodeList;

class node
{
    friend class nodeList;

private:
    int data;
    node* link;

public:
    node(int d = 0) //constructor
        : data(d), link(NULL)
    {
    }
};

class nodeList
{
private:
    node* first;
    int num;

public:
    nodeList()
        : first(NULL), num(0)
    {
    }

    ~nodeList()
    {
        node *n = first, *t;
        while (n)
        {
            t = n->link;
            delete n;
            n = t;
        }
    }

    void add(int data) //add 'data' at the end of the list
    {
        node* n = new node(data);
        if (!first)
            first = n;
        else
        {
            node *t = first;
            while (t->link)
                t = t->link;
            t->link = n;
        }
        ++num;
    }

    void del(int data) //data : data of element that you want to delete from list
    {
        node* n = first;
        node* prev = NULL;

        while (n) //loop to find 'data'
        { 
            if (data == n->data)
            {
                if (prev)
                    prev->link = n->link;
                if (n == first)
                    first = n->link;
                delete n;
                --num;
                return;
            }
            prev = n;
            n = n->link;
        }
    }

    void printList()
    {
        for(node* n = first; n != NULL; n = n->link)
            cout << n->data << endl;
    }
};

int main()
{
    nodeList l;
    int input;
    bool keepGoing = true;

    do
    {
        cout << "1. ADD  2. DELETE  3. PRINT  4. EXIT" << endl;
        if (!(cin >> input))
        {
            cout << "Wrong input" << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
        }
        else
        {
            switch (input)
            {
                case 1:
                    cout << "Enter an integer: ";
                    if (!(cin >> input))
                    {
                        cout << "Wrong input" << endl;
                        cin.clear();
                        cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
                    }
                    else
                    {
                        l.add(input);
                        l.printList();
                    }
                    break;

                case 2:
                    cout << "Enter the data of the element you want to delete: ";
                    if(!(cin >> input))
                    {
                        cout << "Wrong input" << endl;
                        cin.clear();
                        cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
                    }
                    else
                    {
                        l.del(input);
                        l.printList();
                    }
                    break;

                case 3:
                    l.printList();
                    break;

                case 4:
                    keepGoing = false;
                    break;

                default:
                    cout << "Wrong input" << endl;
                    cin.clear();
                    cin.ignore(numeric_limits<streamsize_t>::max(), '\n');
                    break;
            }
        }
    }
    while (keepGoing);

    return 0;
}

如果您在node*课程中添加了额外的nodeList成员,则可以简化并加快add()方法:

class nodeList
{
private:
    node* first;
    node* last;
    int num;

public:
    nodeList()
        : first(NULL), last(NULL), num(0)
    {
    }

    ~nodeList()
    {
        node *n = first, *t;
        while (n)
        {
            t = n->link;
            delete n;
            n = t;
        }
    }

    void add(int data) //add 'data' at the end of the list
    {
        node* n = new node(data);
        if (!first)
            first = n;
        if (last)
            last->link = n;
        last = n;
        ++num;
    }

    void del(int data) //data : data of element that you want to delete from list
    {
        node* n = first;
        node* prev = NULL;

        while (n) //loop to find 'data'
        { 
            if (data == n->data)
            {
                if (prev)
                    prev->link = n->link;
                if (n == first)
                    first = n->link;
                if (n == last)
                   last = prev;
                delete n;
                --num;
                return;
            }
            prev = n;
            n = n->link;
        }
    }

    void printList()
    {
        for(node* n = first; n != NULL; n = n->link)
            cout << n->data << endl;
    }
};

如果您可以将列表更改为双链表而不是单链表,则可以简化del()方法:

#include <iostream>
#include <limits>

using namespace std;

class nodeList;

class node
{
    friend class nodeList;

private:
    int data;
    node* prev;
    node* next;

public:
    node(int d = 0) //constructor
        : data(d), prev(NULL), next(NULL)
    {
    }
};

class nodeList
{
private:
    node* first;
    node* last;
    int num;

public:
    nodeList()
        : first(NULL), last(NULL), num(0)
    {
    }

    ~nodeList()
    {
        node *n = first, *t;
        while (n)
        {
            t = n->next;
            delete n;
            n = t;
        }
    }

    void add(int data) //add 'data' at the end of the list
    {
        node* n = new node(data);
        if (!first)
            first = n;
        if (last)
            last->next = n;
        n->prev = last;
        last = n;
        ++num;
    }

    void del(int data) //data : data of element that you want to delete from list
    {
        for(node* n = first; n != NULL; n = n->next) //loop to find 'data'
        { 
            if (data == n->data)
            {
                if (n->prev)
                    n->prev->next = n->next;
                if (n->next)
                    n->next->prev = n->prev;
                if (n == first)
                    first = n->next;
                if (n == last)
                    last = n->prev;
                delete n;
                --num;
                return;
            }
        }
    }

    void printList()
    {
        for(node* n = first; n != NULL; n = n->next)
            cout << n->data << endl;
    }
};