首页 > 解决方案 > 单链表按顺序插入和删除值

问题描述

我的任务是创建函数来添加和删除链表中的节点,给定输入数据作为 int 和要调用的函数的 char。我不确定我做错了什么。我得到的唯一错误是:退出并返回代码 -11 (SIGSEGV)。还有一个编译器方法:main.cpp: In function 'void listInsertValue(ListNode*&, ListNode*&, int)': main.cpp:111:23: warning: 'toGoAfter' may be used uninitialized in this function [-Wmaybe -未初始化] 111 | toGoAfter->next = head;

任何帮助表示赞赏。谢谢!

#include <iostream>
using namespace std;

struct ListNode
{
    int data;
    ListNode* next;
};

void listRemoveAfter(ListNode*&, ListNode*&, ListNode*);
void listPrepend(ListNode*&, ListNode*&, ListNode*&);
void listDeleteValue(ListNode*&, ListNode*&, int);
void listInsertValue(ListNode*&, ListNode*&, int);
void listInsertAfter(ListNode*&, ListNode*&, ListNode*, ListNode*);

int main()
{
    
    ListNode *head = nullptr, *tail = nullptr;
    ListNode *temp;
   char choice;
   int val;

   //Write a main like you did in the previous lab
   char command;
   int number;
   
   cin >> command;
   while(command != 'Q')
   {
        if(command == 'I')
        {
            cin >> number;
            listInsertValue(head,tail,number);
        }
        else
        {
            cin >> number;
            listDeleteValue(head,tail,number);
        }
        
      cin >> command;
   }
   ListNode* current;
   current = head;
    while (current != nullptr)
    {
        cout << current->data << " ";
        current = current->next;
    }
    cout << endl;
    return 0;

}

//From previous lab - already complete
void listPrepend(ListNode*& h, ListNode*& t, ListNode*& n)
{
    if (h == nullptr)
    {
        h = n;
        t = n;
    }
    else
    {
        n->next = h;
        h = n;
    }
}

//From book, write yourself using the book code in 17.6 as a starting point
void listInsertAfter(ListNode*&head, ListNode*&tail, ListNode* curNode, ListNode* newNode)
{
   if (head->next == nullptr) 
   { 
      head= newNode;
      tail = newNode;
   }
   else if (curNode->next == tail) 
   { 
      tail->next = newNode;
      tail = newNode;
   }
   else 
   {
      newNode->next = curNode;
      curNode->next = newNode;
   }
}


//This function is mostly written, but you will need to add some code near the TODOs to complete the algorithm from the slides
void listInsertValue(ListNode*& head, ListNode*& tail, int val)
{
    ListNode* toGoAfter, *newNode;

   //TODO - create a new ListNode (newNode) with a data value of val (3 lines of code)
   newNode = new ListNode;
   newNode->data = val;
   newNode->next = nullptr;
    //TODO - check whether the list is empty in the if condition
    if (head == nullptr)
    {
        listInsertAfter(head, tail, nullptr, newNode);
    }
    //TODO - use the else if to check whether the the value passed in is smaller than the value in the head
    else if (head->data > val)  //need to add to beginning of the list
    {
        listPrepend(head, tail, newNode);
    }
    else //need to add somewhere else in the list
    {
       //TODO - set toGoAfter to point to the head
      toGoAfter->next = head;
      //loop to find the location to insert the value
        while (toGoAfter->next != nullptr && toGoAfter->next->data < val)
        {
           //TODO - set toGoAfter to point to the node after toGoAfter, like is done in traversals
           toGoAfter = toGoAfter->next;
        }

      //We have found the location, so we can insert
        listInsertAfter(head, tail, toGoAfter, newNode);

    }
}

//modify
void listDeleteValue(ListNode* &head, ListNode*& tail, int val)
{
    ListNode *temp;

   //TODO - check if list is not empty in if condition
    if (head->next == nullptr)
    {
       // TODO - check if value of head matches val passed in
        if (head->data == val)
            listRemoveAfter(head, tail, nullptr);
    }
        else
        {
           //loop searches for value to delete in node following temp
           //TODO - set temp to point to the head
           temp->next = head;
            while (temp->next != nullptr && temp->next->data != val)
            {
               //TODO - set temp to point to the node after temp, like is done in traversals
               temp = temp->next;
            }

         //TODO - make sure a node exists after temp, meaning the value to delete was found
            if (temp->next != nullptr)
                listRemoveAfter(head, tail, temp);
        }
    
}

//From book, write yourself using the book code in 17.7 as a starting point
//Also add to the book's code, the code to delete nodes from memory
void listRemoveAfter(ListNode* & head, ListNode*& tail, ListNode* curNode) 
{
    ListNode *sucNode, *toDelete;
    
     if (curNode->next == nullptr && head->next != nullptr) 
     {
       sucNode = head->next;
      head->next = sucNode;

      if (sucNode->next == nullptr) 
      { // Removed last item
         tail->next = nullptr;
         toDelete = head;
      }
   }
   else if (curNode->next != nullptr)
   {
      sucNode = curNode->next->next;
      curNode->next = sucNode;

      if (sucNode-> next == nullptr)
      { // Removed tail
         tail->next = curNode;
         toDelete = curNode->next;
      }
      
   }

    delete toDelete;  //needed after the if/else if to remove the deleted node from memory

}

标签: c++linked-listnodes

解决方案


在大多数情况下,当列表中没有元素时,您不会处理这种情况。插入手柄时 4 个用例

  1. 头==nullptr => 头=newNode;
  2. 头部->数据> val
  3. 尾->数据 < val
  4. else case : 插入中间

一般错误:当 ptr 为 nullptr 时访问 ptr-> next

通常,您想使用调试器,并且对内存 0x0 (nullptr) 的任何访问都将开始解决您的问题。即 head 是 0x0 并且您正在执行诸如 head->data ==val 之类的操作


推荐阅读