【问题标题】:How do I delete a specific node in a linked list如何删除链表中的特定节点
【发布时间】:2020-02-11 12:37:49
【问题描述】:

我面临一个问题,我似乎无法找到特定节点,然后从链接列表中删除该节点。我试图创建最后显示的while循环,循环两次包含节点的head的内存分配,然后删除它,但如果我将deleteNode设置为2,它似乎会删除两个节点。

void delete_list(Book *&head, Book *&last){
    if (head == NULL)
    {
        cout << "Database is already empty! \n";
    }
    else if (head == last){
        delete head;
        head = NULL;
        last = NULL;
    }
    else
    {
        cout << "Please enter the number of the node you would like to delete \n";
        cin >> deleteNode;

        Book* new_book = head;

        while(deleteNode>0) {
            head = head -> next;
            deleteNode--;
        }
        delete new_book;
    }
}

#include <iostream>
#include <string>
using namespace std;



struct Book{

    string title;
    string author;
    string publisher;
    int publishYear;
    int isbn;
    Book* next;
};

void add_node(Book*&, Book*&);
void print_list(Book*);
void delete_list(Book*& , Book*& );
int deleteNode;


int main()
{

    Book* head = NULL;
    Book* last = NULL;

  char option;
    do{

        cout << "Press required option: \n" "To Add Book detail   [A]\n"
                "To Print Book details   [P]\n" "To Delete Book details   [D]\n"
                "Quit  [Q]\n";
                cin >> option;

      switch(option){
          case 'A':
          add_node(head, last);
          break;

          case 'P':
          print_list(head);
          break;

          case 'D':
          delete_list(head, last);

          case 'Q':
          break;

          default:
          cout << "Invalid Input" << endl;

      }
    } while (option != 'Q');

    return 0;
}


void add_node(Book *&head, Book *&last){
    //Cheaks the empty link list
    if (head == NULL){

    Book* new_book = new Book();

    cout <<"Enter Book name \n";
    cin >> new_book -> title;

    cout << "Enter author name \n";
    cin >> new_book -> author;


    cout << "Enter publisher name \n";
    cin >> new_book -> publisher;

    cout << "Enter publish year \n";
    cin >> new_book -> publishYear;

    cout << "Enter ISBN number \n";
    cin >> new_book -> isbn;


    new_book -> next = NULL;
    head = new_book;
    last = new_book;

    }

    else
    {
        Book* new_book1 = new Book;

    cout <<"Enter Book name \n";
    cin >> new_book1 -> title;

    cout << "Enter author name \n";
    cin >> new_book1 -> author;


    cout << "Enter publisher name \n";
    cin >> new_book1 -> publisher;

    cout << "Enter publish year \n";
    cin >> new_book1 -> publishYear;

    cout << "Enter ISBN number \n";
    cin >> new_book1 -> isbn;


        last -> next = new_book1;
        last =  new_book1;
    }

}


void print_list(Book* in_root){

    Book* next_ptr;
    next_ptr = in_root;
    if(next_ptr == NULL)
    {
        cout << "No information found! \n";

    }

    else
    {
        while (next_ptr != NULL){
            cout << "Book Name: "<<next_ptr -> title << endl;
            cout << "Author Name: "<<next_ptr -> author << endl;
            cout << "Publisher: "<<next_ptr -> publisher << endl;
            cout << "Publishing Year: "<<next_ptr -> publishYear << endl;
            cout << "ISBN Number: "<<next_ptr -> isbn << endl;
            cout << " \n";
            next_ptr = next_ptr -> next;
        }
    }
}


void delete_list(Book *&head, Book *&last){


    if (head == NULL)
    {
        cout << "Database is already empty! \n";
    }

    else if (head == last){
        delete head;
        head = NULL;
        last = NULL;
    }

    else
    {
        cout << "Please enter the number of the node you would like to delete \n";
        cin >> deleteNode;

        Book* new_book = head;

      while(deleteNode>0){

        head = head -> next;
        deleteNode--;
      }
      delete new_book;
    }
}

【问题讨论】:

  • 请为我们提供完整的工作示例,以便我们轻松测试。
  • 我喜欢函数参数是引用指针
  • @NutCracker 我已经提供了完整的代码。它应该是一个程序,将书籍信息存储在节点的动态内存中,用户可以删除特定书籍及其所有信息
  • 删除单链表中的 any 节点涉及一件事:找到指向该节点的指针并从列表中删除该节点。该指针可以是 (a) head 指针,或 (b) 某个其他节点中的某个 next 指针。没有其他选择。并且仅供参考,当使用指针指向实际列表时,这更容易(恕我直言)。

标签: c++ pointers dynamic linked-list structure


【解决方案1】:

你很接近。你在这里有几个问题。首先,当您执行head = head-&gt;next 遍历您的列表时,您正在积极地重新分配头指针,因此会从列表中丢失节点。您应该创建一个临时节点,通常称为curr for current。然后设置curr = head并在while循环中执行curr = curr-&gt;next

另一个问题是您删除了列表中间的一个节点,这实际上将您的列表分成两部分,但不要将这两部分重新组合在一起。您需要创建另一个临时变量来指向要删除的节点Book* deleteMe = curr-&gt;next。设置curr-&gt;next = curr-&gt;next-&gt;next 然后delete deleteMe

【讨论】:

    【解决方案2】:

    您没有更新被删除节点包围的节点。从列表的前面或后面删除节点时,您不会更新 headlast 指针。而且您在简单地迭代列表的同时更新调用者的head 指针,从而有效地破坏了调用者的列表。

    试试这个:

    void delete_list(Book* &head, Book* &last)
    {
        if (!head)
        {
            cout << "Database is already empty! \n";
        }
        else
        {
            cout << "Please enter the number of the node you would like to delete \n";
            int deleteNode = -1;
            cin >> deleteNode;
    
            if (deleteNode < 1)
            {
                cout << "Invalid node number \n";
                return;
            }
    
            Book* book = head, *previous = NULL;
    
            while ((book) && (--deleteNode > 0))
            {
                previous = book;
                book = book->next;
            }
    
            if (!book)
            {
                cout << "Invalid node number \n";
                return;
            }
    
            if (previous)
                previous->next = book->next;
    
            if (head == book)
                head = book->next;
    
            if (last == book)
                last = previous;
    
            delete book;
        }
    }
    

    也就是说,您的代码还有其他一些问题。尝试更多类似的方法:

    #include <iostream>
    #include <string>
    #include <limits>
    using namespace std;
    
    struct Book
    {
        string title;
        string author;
        string publisher;
        int publishYear;
        int isbn;
    
        Book* next;
    };
    
    void add_node(Book*&, Book*&);
    void print_list(Book*);
    void delete_list(Book*&, Book*&);
    
    int main()
    {
        Book* head = NULL;
        Book* last = NULL;
    
        char option;
    
        do
        {
            cout << "Press required option: \n"
                    "To Add Book detail   [A]\n"
                    "To Print Book details   [P]\n"
                    "To Delete Book details   [D]\n"
                    "Quit  [Q]\n";
    
            if (!(cin >> option))
            {
                option = '\0';
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                continue;
            }
    
            switch (option)
            {
                case 'A':
                    add_node(head, last);
                    break;
    
                case 'P':
                    print_list(head);
                    break;
    
                case 'D':
                    delete_list(head, last);
                    break;
    
                case 'Q':
                    break;
    
                default:
                    cout << "Invalid Input" << endl;
                    cin.ignore(numeric_limits<streamsize>::max(), '\n');
                    break;
            }
        }
        while (option != 'Q');
    
        return 0;
    }
    
    void add_node(Book *&head, Book *&last)
    {
        Book* new_book = new Book;
    
        cout << "Enter Book name \n";
        getline(cin, new_book->title);
    
        cout << "Enter author name \n";
        getline(cin, new_book->author);
    
        cout << "Enter publisher name \n";
        getline(cin, new_book->publisher);
    
        cout << "Enter publish year \n";
        cin >> new_book->publishYear;
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    
        cout << "Enter ISBN number \n";
        cin >> new_book->isbn;
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
    
        new_book->next = NULL;
    
        //Checks the empty link list
        if (!head) {
            head = last = new_book;
        }
        else
        {
            last->next = new_book;
            last = new_book;
        }
    }
    
    void print_list(Book* root)
    {
        if (!root)
        {
            cout << "No information found! \n";
            return;
        }
    
        Book* book = root;
        do
        {
            cout << "Book Name: " << book->title << endl;
            cout << "Author Name: " << book->author << endl;
            cout << "Publisher: " << book->publisher << endl;
            cout << "Publishing Year: " << book->publishYear << endl;
            cout << "ISBN Number: " << book->isbn << endl;
            cout << " \n";
            book = book->next;
        }
        while (book);
    }
    
    void delete_list(Book* &head, Book* &last)
    {
        if (!head)
        {
            cout << "Database is already empty! \n";
        }
        else
        {
            cout << "Please enter the number of the node you would like to delete \n";
    
            int deleteNode;
            if (!(cin >> deleteNode))
            {
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(), '\n');
                cout << "Invalid Input" << endl;
                return;
            }
    
            if (deleteNode < 1)
            {
                cout << "Invalid node number \n";
                return;
            }
    
            Book* book = head, *previous = NULL;
    
            while ((book) && (--deleteNode > 0))
            {
                previous = book;
                book = book->next;
            }
    
            if (!book)
            {
                cout << "Invalid node number \n";
                return;
            }
    
            if (previous)
                previous->next = book->next;
    
            if (head == book)
                head = book->next;
    
            if (last == book)
                last = previous;
    
            delete book;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-23
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 2018-05-09
      • 2018-09-02
      • 1970-01-01
      相关资源
      最近更新 更多