当前位置: 首页 > 知识库问答 >
问题:

单链表按顺序插入和删除值

邵星河
2023-03-14

我的任务是创建函数来添加和删除链表中的节点,输入数据为int,字符为with函数调用。我不确定我做错了什么。我得到的唯一错误是:退出时返回代码为-11(SIGSEGV)。还有一个编译器方法:main。cpp:在函数“void listInsertValue(ListNode)”中*

感谢任何帮助。谢谢!

#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

}

共有1个答案

单于山
2023-03-14

在大多数情况下,当列表中没有任何元素时,您并没有处理该案例。在插入4个用例时

  1. 头==nullptr=

一般错误:访问ptr-

通常情况下,您希望使用调试器,对内存0x0(nullptr)的任何访问都将开始解决您的问题。ie head是0x0,你正在做一个类似head的操作-

 类似资料:
  • 问题内容: 如何以以下方式将值插入表(MySQL): 在表的所有行上,按ID列(PK)的顺序,在“ num”列中插入递增数字? 例如,如果表有3行,其ID为1,5,2,我希望ID 1获得num = 1,ID 2获得num = 2,ID 5获得num = 3。 编辑 我将解释为什么(我认为)需要这样做: 我试图将表中的列拆分为具有1对1关系的单独表。我以为我可以按ID的顺序获取所有值,然后将它们插入

  • 我在做单链表实现,我记得Linus Torvalds在这里谈到过。 在单链表中,为了删除节点,我们应该可以访问上一个节点,然后更改它当前指向的节点。 因此,无论如何,我们都应该可以访问上一个节点。 但是Linus Torvalds通过在C中使用地址的概念删除了这个特例。因此head也有“前面的东西”,即指向head的head的地址。因此,他使用了C的指针和地址特性来删除特殊情况。 我认为这种单链表

  • 问题内容: 我在Oracle中有两个表,作业和参考。 我想在两个表中插入一条新记录,并使用从序列中生成的键。就像是: 当然,这导致: 有没有不使用PL / SQL的方法?我非常喜欢仅使用SQL来做到这一点。 问题答案: 您可以为此使用多表插入语法的副作用: SQL小提琴。 从限制: 您不能在多表插入语句的任何部分中指定序列。多表插入被视为单个SQL语句。因此,对NEXTVAL的第一个引用将生成下一

  • 我试图做一个哈希表与线性探测插入。 表的大小是11,我的散列函数是,h(k)=k mod 11,我想做的是。 插入(15, c)插入(4, a)插入(26, b)删除(15)插入(5, d)插入(4, e) 这是我的解决方案,但它是不对的。 应该是这样的,有人能解释一下为什么吗?

  • 问题内容: 首先让我们忘记hibernate。假设我有两个表A和B。两个事务正在更新这两个表中的相同记录,但是txn 1更新B然后A,而txn 2更新A然后B。这是一个典型的死锁示例。避免这种情况的最常见方法是预先定义获取资源的顺序。例如,我们应该先更新表A然后再更新表B。 回到hibernate状态。当我们在一个会话中更新大量实体时,一旦刷新会话,对不同实体的更改将为数据库生成相应的插入/更新/

  • 让我们先忘记Hibernate。假设我有两张表,一张 回去冬眠吧。当我们在一个会话中更新大量实体时,一旦我刷新会话,不同实体的更改将会向数据库生成相应的插入/更新/删除语句。Hibernate有什么算法来决定实体之间的更新顺序吗?如果不是,Hibernate用来防止第一段描述的死锁情况的方法是什么? 如果Hibernate正在维持订单,我如何知道或控制订单?我不希望我在数据库中的显式更新与Hibe