单链表按顺序插入和删除值
Posted
技术标签:
【中文标题】单链表按顺序插入和删除值【英文标题】: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->next == nullptr)
时,BOOM :) 另一个问题等待着您。祝你好运:)
我认为您可能对toGoAfter->next = head;
有疑问。您从未将toGoAfter
设置为任何值,但您仍在尝试将其设置为next
值。我认为在那一行中你只想要toGoAfter = head;
以便toGoAfter
它自己 指向头部。
链接列表是一个非常重要的概念,您需要确保自己非常了解。当您为此苦苦挣扎时,我将向您推荐谷歌“链表教程”,然后找到一个看起来不错的。如果您以这种方式学得很好,最近 YouTube 上有一些很棒的教程。花时间去真正理解是值得的。
【参考方案1】:
在大多数情况下,当列表中没有元素时,您不会处理这种情况。插入句柄4用例时
-
head==nullptr => head =newNode;
head->数据> val
尾部->数据
一般错误:访问ptr-> next,当ptr为nullptr时
一般来说,您希望使用调试器,并且对内存 0x0 (nullptr) 的任何访问都将开始解决您的问题。即 head 是 0x0 并且您正在执行 head->data ==val
之类的操作【讨论】:
以上是关于单链表按顺序插入和删除值的主要内容,如果未能解决你的问题,请参考以下文章