【问题标题】:Singly Linked List inserting and deleting value in order单链表按顺序插入和删除值
【发布时间】:2021-06-15 22:11:57
【问题描述】:

我的任务是创建函数来添加和删除链表中的节点,给定输入数据作为 int 和要调用的函数的 char。我不确定我做错了什么。我得到的唯一错误是:退出并返回代码 -11 (SIGSEGV)。还有一个编译器方法:main.cpp:在函数‘void listInsertValue(ListNode*&, ListNode*&, int)’中: main.cpp:111:23:警告:“toGoAfter”可能在此函数中未初始化使用 [-Wmaybe-uninitialized] 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

}

【问题讨论】:

  • 建议 -- 摆脱cin 语句并使用导致问题的已知数据直接调用函数。这允许您(和其他人)直接运行代码,而无需在每次运行程序时都输入。
  • 您的第一个问题确实出在listInsertValue 函数中。在您的第一次插入中,您调用listInsertAfter 并以head 作为第一个参数......但是您刚刚检查了head == nullptr 所以....当您尝试检查if(head-&gt;next == nullptr) 时,BOOM :) 另一个问题等待着您。祝你好运:)
  • 我认为您可能对toGoAfter-&gt;next = head; 有疑问。您从未将toGoAfter 设置为任何值,但您仍在尝试将其设置为next 值。我认为在那一行中你只想要toGoAfter = head; 以便toGoAfter 它自己 指向头部。
  • 链接列表是一个非常重要的概念,您需要确保自己非常了解。当您为此苦苦挣扎时,我将向您推荐谷歌“链表教程”,然后找到一个看起来不错的。如果您以这种方式学得很好,最近 YouTube 上有一些很棒的教程。花时间去真正理解是值得的。

标签: c++ linked-list nodes


【解决方案1】:

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

  1. head==nullptr => head =newNode;
  2. head->数据> val
  3. 尾部->数据
  4. 其他情况:插入中间

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

一般来说,您希望使用调试器,并且对内存 0x0 (nullptr) 的任何访问都将开始解决您的问题。即 head 是 0x0 并且您正在执行 head->data ==val

之类的操作

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    相关资源
    最近更新 更多