【问题标题】:How to delete a node in a linked list?如何删除链表中的节点?
【发布时间】:2018-05-09 12:56:18
【问题描述】:

这是我目前所拥有的,但它不起作用。基本上跳到else if(cnode == preposition)

void LinkedList::Delete(Node *PrePosition) {

    Node *cnode = head;
    Node *pnode = NULL;
    while (cnode != NULL) {
        if (cnode->value != NULL) {
            if (pnode == NULL) {
                // if there is not previous node
                head = cnode->next;
            }
            else if (cnode == PrePosition) {
                // if there is previous node
                cout << endl << "Deleting: " << cnode << endl;
                pnode->next = cnode->next;
            }
        }
        else {
            // don't delete
            pnode = cnode;
        }
        cnode = cnode->next;
    }
}

【问题讨论】:

  • 如果PrePosition真的是要删除的节点之前的节点,那么这看起来更像是对常识的测试。但这可能永远是提问者的秘密。

标签: c++ nodes


【解决方案1】:

1:从上一个节点中取出指针,指向要删除的节点之后的下一个节点

2:删除上一个节点指向当前节点的指针

3:删除从下一个节点指向当前节点的指针(如果是双向链表)

【讨论】:

    【解决方案2】:

    单链表删除的三种情况:

    1. 删除第一个节点

      void delete_first()
      {
          node *temp=new node;
          temp=head;
          head=head->next;
          delete temp;
      }
      
    2. 删除最后一个节点

      void delete_last()
      {
          node *current = new node;
          node *previous = new node;
          current=head;
          while(current->next != NULL)
          {
            previous = current;
            current = current->next;  
          }
          tail = previous; // if you have a Node* tail member in your LinkedList
          previous->next = NULL;
          delete current;
      }
      
    3. 在特定位置删除(您的情况)

      void LinkedList::delete_position(int pos)
      {
          node *current=new node;
          node *previous=new node;
          current=head;
          for(int i=1; i < pos; i++) //or i = 0; i < pos-1
          {
             previous=current;
             current=current->next;
          }
          previous->next=current->next;
          delete current;
      }
      

      ^^ 来自codementor ^^

    但是,如果您的函数签名打算使用 delete_node(Node* nodeToDelete) [PrePosition 在这种情况下不是一个好名字],并且您想删除传递给函数的节点而不知道它在列表中的位置,我们可以像这样修改 delete_position():

    void LinkedList::delete_node(Node* nodeToDelete)
    {
        node *current= head;
        node *previous= nullptr;
    
        if (head == nodeToDelete){
            head = nodeToDelete->next;
            delete nodeToDelete;
            return
        }//else
        while(current != nodeToDelete)
        {
            previous = current;
            current = current->next
        }
        previous->next = current->next;
        delete nodeToDelete;
    }
    

    同样在您的原始代码中,如果它跳过了您提到的那一行,当 cnode 中包含非空值时,pnode 始终为空。

    【讨论】:

    • 如果你已经有一个指向前一个位置的指针,为什么要迭代列表来找到它?
    • @user4581301 因为它是一个单链表,所以你不能只删除指针。您必须迭代才能找到前一个节点。我认为虽然我在 OPs 的情况下假设错误,但指针很可能是它的名字所暗示的:指向要删除的节点之前的节点的指针。
    • 有一个非常巧妙的技巧,可以使用指向指针的指针来解决这个问题。与其传入指向要删除的节点的指针,不如传入指向所需下一个指针的指针更新。函数看起来像void LinkedList::delete_node(Node** nodeToDelete) { if (*nodeToDelete) { node * temp = *nodeToDelete; *nodeToDelete = (*nodeToDelete)-&gt;next; delete temp; } }Variant of the alternative provided here.(stackoverflow.com/a/22122095/4581301)
    【解决方案3】:

    这里是完整的代码

        class SportShoe  {
        private:
            struct nodeSport {
                int ShoeID;
                char BrandShoe[SIZE]; 
                char TypeShoe[SIZE];
                char ColourShoe[SIZE];
                int SizeShoe;
                float PriceShoe; 
                nodeSport *last;
                };
                nodeSport *first = NULL; 
    
        public:
            int MenuSportShoe();
            void AddSportShoe();
            void DisplaySportShoe();
            void DeleteSportShoe();
            static void ExitSportShoe();
        };
    
       int SportShoe::MenuSportShoe() {
         int OptionSportShoe = 0;
    
        cout << endl;
        cout << "Please select from the menu:" << endl;
        cout << ":: 1 :: Add item to shoe list" << endl;
        cout << ":: 2 :: Display shoes list" << endl;
        cout << ":: 3 :: Delete item from the list" << endl;
        cout << ":: 4 :: Back" << endl;
        cout << "=>> ";
        cin >> OptionSportShoe;
    
        while (OptionSportShoe == 1){
            AddSportShoe();
        }
    
        while (OptionSportShoe == 2){
            DisplaySportShoe();
          }
    
        while (OptionSportShoe == 3){
            DeleteSportShoe();
        }
    
        while (OptionSportShoe == 4){
            ExitSportShoe();
        }
    
        return 0;
      }
    
    void SportShoe::AddSportShoe() {    
        nodeSport *tempShoe1, *tempShoe2; 
    
        tempShoe1 = new nodeSport;
        cout << "Please enter the Shoe ID : (eg. 43210) " << endl;
        cout << "=>> ";
        cin >> tempShoe1->ShoeID;
    
        cout << "Please enter the Shoe Brand: (eg. Adidas) " << endl;
        cout << "=>> ";
        cin.sync();
        cin.getline(tempShoe1->BrandShoe,SIZE);
    
        cout << "Please enter the Shoe Type : (eg. Running) " << endl;
        cout << "=>> ";
        cin.sync();
        cin.getline(tempShoe1->TypeShoe,SIZE);
    
        cout << "What is the Shoe Colour : (eg. Grey) " << endl;
        cout << "=>> ";
        cin.sync();
        cin.getline(tempShoe1->ColourShoe,SIZE);
    
        cout << "Please enter Shoe Size : (eg. 9) " << endl;
        cout << "=>> ";
        cin >> tempShoe1->SizeShoe; 
    
        cout << "Please enter the price of the Shoe : (eg. RM123.45) " << endl;
        cout << "=>> RM ";
        cin >> tempShoe1->PriceShoe;
    
    
        tempShoe1->last = NULL;  
    
    
        if (first == NULL)  
            first = tempShoe1;
        else  
        {
            tempShoe2 = first; 
            while (tempShoe2->last != NULL) 
                tempShoe2 = tempShoe2->last;
    
            tempShoe2->last = tempShoe1;
        }
    
        system("PAUSE");
        MenuSportShoe();
      }
    
    void SportShoe::DisplaySportShoe() {
        nodeSport *tempShoe1;
        tempShoe1 = first;
    
        while(tempShoe1){
            cout << "ID : " << tempShoe1->ShoeID << endl;
            cout << "Brand : " << tempShoe1->BrandShoe << endl;
            cout << "Type : " << tempShoe1->TypeShoe << endl;
            cout << "Colour : " << tempShoe1->ColourShoe << endl;
            cout << "Size : " << tempShoe1->SizeShoe << endl;
            cout << "Price : " << tempShoe1->PriceShoe << endl;
            cout << endl;
            tempShoe1 = tempShoe1->last;
        }
    
        system("PAUSE");
        MenuSportShoe();
      }
    
     void SportShoe::DeleteSportShoe(){
        nodeSport *tempShoe1, *tempShoe2; 
        int DataShoe;
        tempShoe2 = tempShoe1 = first;
    
        if(tempShoe1 == NULL)
        {
            cout << "\nList is empty!" << endl;
            system("PAUSE");
            MenuSportShoe();
        }
    
        while(tempShoe1 != NULL)
        {
            cout << "\nEnter the Shoes ID to be deleted: (eg. 123) ";
            cin >> DataShoe;
    
            tempShoe2 = tempShoe1;
            tempShoe1 = tempShoe1->last;
    
            if(DataShoe == tempShoe1-> ShoeID){ 
                if(tempShoe1 == first)  {
                    first = first->last;
                    cout << "\nData deleted ";
                }
    
                else{
                    tempShoe2->last = tempShoe1->last;
                    if(tempShoe1->last == NULL){
                        tempShoe2 = tempShoe2;
                    }
                    cout << "\nData deleted ";
                }
    
                delete(tempShoe1);
    
                system("PAUSE");
                MenuSportShoe();
            }
    
            else{
                cout << "\nRecord not Found!!!" << endl;
                system("PAUSE");
                MenuSportShoe();
            }
        }
      }
    
      void SportShoe::ExitSportShoe(){
        int sepatu;
    
        cout << endl;
        cout << "Please choose the option below."<<endl;
        cout << ":: 1 :: Sport Shoe." << endl;
        cout << ":: 2 :: Ladies High Heel." << endl;
        cout << ":: 3 :: Exit" << endl;
        cout << "=>> ";
        cin >> sepatu;
    
        while(sepatu == 1){
            SportShoe listShoe;
            listShoe.MenuSportShoe();
        }
    
        while(sepatu == 2){
            HighHeel listShoe;
            listShoe.MenuHighHeel();
        }
    
        while(sepatu == 3){
            cout << "Thank you. Till we meet again."<< endl;
            exit(1);
        }
    
      }
    
      main() {
    
        cout << "Hello! Welcome to MySepatu Online Shop administrator."<< endl;
        cout << endl;
    
        SportShoe::ExitSportShoe();
        HighHeel::ExitHighHeel();
    
        return 0;
      }
    

    【讨论】:

      【解决方案4】:
      public class linkedList {
          int count = 0;
          
          class Node {
              int element;
              Node next;
              Node(int element) {
                  this.element = element;
              }
          } 
          
          Node head = null;
          Node tail = null;
          
          public void addNode(int Object) {
              Node newNode = new Node(Object);
              if (head == null) {
                  head = tail = newNode;
              } else {
                  tail.next = newNode;
                  tail = newNode;
              }
          }
          
          public void Display() {
              Node current = head;
              while (current!=null) {
                  System.out.println(current.element);
                  count ++;
                  current = current.next;
              }
          }
          
          public void Length() {
              System.out.println(count);   
          }
          
          public void Remove(int node) {
              Node curr = head;
              while (curr!=null) { // looping the nodes
                  if (curr.element == node ) {
                      curr.element = curr.next.element;
                      curr = curr.next;
                      // To fix the Duplicates
                      while (curr!= tail) {
                          curr.element = curr.next.element;
                          curr = curr.next;
                      }
                      RemoveEnd();
                      break;
                  }
                  curr = curr.next;
              }
          }
          
          public void RemoveEnd() {
              Node current3 = head;
              while (current3.next != tail) {
                  current3 = current3.next;
              }
              tail = current3;
              tail.next = null;
          }
      }
      

      【讨论】:

      • 你好杜夫。欢迎来到堆栈溢出。正如您可能已经看到的,它是关于解决编码问题的。当一个问题(及其答案)更多地是关于做“某人的家庭作业”(这已经发生在我身上)时,它们通常会被标记。我真的很困惑这个问题没有被标记,但我想它有一些价值。
      • 请阅读“投票最多”的答案,因为您对特定问题(删除节点)的回答不正确,或者至少效率不高,因为您实际上是将所有数据移入当您只需要从中删除一项时的列表。请修正,否则您的答案将被否决。
      • 即使您的答案背后的想法可能适用,它是在 Java 中,而 OP 正在寻求 C++ 中的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多