c++ - 单链表按顺序插入和删除值
问题描述
我的任务是创建函数来添加和删除链表中的节点,给定输入数据作为 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
}
解决方案
在大多数情况下,当列表中没有元素时,您不会处理这种情况。插入手柄时 4 个用例
- 头==nullptr => 头=newNode;
- 头部->数据> val
- 尾->数据 < val
- else case : 插入中间
一般错误:当 ptr 为 nullptr 时访问 ptr-> next
通常,您想使用调试器,并且对内存 0x0 (nullptr) 的任何访问都将开始解决您的问题。即 head 是 0x0 并且您正在执行诸如 head->data ==val 之类的操作
推荐阅读
- asp.net-core - 正确的 ASP.NET Core 5 的 JWT nuget 包
- salesforce - 有没有办法在闪电模式弹出窗口中删除保存和取消
- python - 提取几个句子共有的 ngram
- python - 在 Python 中将 2 个 csv 文件与新行合并
- linux - 经常获取 - 连接到您的实例时出现问题(不是第一次设置)
- intellij-idea - 无法在 IntelliJ 上添加原型
- javascript - 如果为 null,则修改对象数组以替换为其他属性
- postgresql - Postgresql:使用具有唯一约束的相同ID“更新”到两个表中
- azure - Terraform 创建和引导 Azure 订阅
- c# - 如何获取excel临时文件的内容?