尝试将上一个节点链接到要删除的节点之后的节点时出错
Error while trying link previous node to the node after the node to be deleted
对于这个作业,我应该创建一个带有插入函数、删除函数和反向函数的链表。它使用输入文件获取列表的值,并使用另一个输入文件来删除值。我的插入和反向函数有效,但是当我尝试将前一个节点链接到 nodeptr 之后的节点时,我的删除函数在 else 语句中给我一个错误。它说使用了可能未初始化的本地指针变量"previousNodePtr"。我不确定我做错了什么来重新链接我的列表,以便我可以删除所需的节点。您可以在删除功能中找到我的问题大约 90 行。这是我的代码:
//use a linked list to maintain a sorted list of numbers in descending
//order
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
const int ARRAY_SIZE = 100;
//input the data from a file to an array A, n is used to calculate the total number of
//data in the file
void input(int A[], int & n, const string & fileName)
{
ifstream inputFile;
int value;
inputFile.open(fileName.c_str());
if (!inputFile)
{
cout << "Error opening the file " << fileName << endl;
exit(0);
}
//read data until the end of the file and calculate n
while(inputFile >> value)
{
A[n] = value;
n++;
}
inputFile.close();
}
struct ListNode
{
int value;
ListNode *next;
//struct constructor
ListNode (int input_value, ListNode * input_next = NULL)
{
value = input_value;
next = input_next;
}
};
//define a class for the linked list
class LinkedList
{
private:
ListNode *head;// the head of the linked list
public:
LinkedList() {head = NULL;}
~LinkedList();
void insert(int x);// add a number x the end of the list
void remove(int x);//remove x from the list
void reverse();//reverse the list
void printListToFile(const string & fileName) const; // print the list to a file
void printList() const; // print the list to the console (computer's screen), this function may be helpful when you test your program
};
//insert
void LinkedList::insert(int x)
{
ListNode *nodePtr, *previousNodePtr;
if (head == NULL || head->value <= x)
{
head = new ListNode(x, head);
}
else
{
previousNodePtr = head;
nodePtr = head->next;
while (nodePtr != NULL && nodePtr->value > x)
{
previousNodePtr = nodePtr;
nodePtr = nodePtr->next;
}
previousNodePtr->next = new ListNode(x, nodePtr);
}
}
//remove
void LinkedList::remove(int x)
{
ListNode *nodePtr, *previousNodePtr;
if (!head) return;
if (head->value == x)
{
nodePtr = head;
head = head->next;
delete nodePtr;
}
else
{
nodePtr = head;
while (nodePtr != NULL && nodePtr->value != x)
{
previousNodePtr = nodePtr;
nodePtr = nodePtr->next;
}
if (nodePtr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
}
}
}
//reverse
void LinkedList::reverse()
{
ListNode *nodePtr, *previousNodePtr, *nodeNext;
nodePtr = head;
nodeNext = NULL;
previousNodePtr = NULL;
while (nodePtr != NULL)
{
nodeNext = nodePtr->next;
nodePtr->next = previousNodePtr;
previousNodePtr = nodePtr;
nodePtr = nodeNext;
}
head = previousNodePtr;
}
void LinkedList::printList() const
{
ListNode *p = head;
while (p != NULL)
{
if (p->next == NULL)
cout << p->value << endl;
else
cout << p->value << " -> ";
p = p->next;
}
}
void LinkedList::printListToFile(const string & fileName) const
{
ofstream outputFile;
outputFile.open(fileName.c_str());
if (!outputFile)
{
cout << "Error opening the file " << fileName << endl;
exit(0);
}
ListNode *p = head;
while (p != NULL)
{
if (p->next == NULL)
outputFile << p->value << endl;
else
outputFile << p->value << " -> ";
p = p->next;
}
outputFile.close();
}
//destructor, delete all nodes
LinkedList::~LinkedList()
{
ListNode *p = head;
while (p != NULL)
{
ListNode * garbageNode = p;
p = p->next;
delete garbageNode;
}
}
int main()
{
int A[ARRAY_SIZE];// store numbers for insert
int B[ARRAY_SIZE]; // store numbers for remove
int n = 0;// the number of elements that will be stored in A
int m = 0;// the number of elements that will be stored in B
string inputFile1 = "hw2_Q1_insertData.txt"; // file with data for insert
string inputFile2 = "hw2_Q1_removeData.txt"; // file with data for remove
//input data from the two files
input(A, n, inputFile1);
input(B, m, inputFile2);
LinkedList list;
//do insert operations
for (int i = 0; i < n; i++)
list.insert(A[i]);
//do remove operations
for (int i = 0; i < m; i++)
list.remove(B[i]);
//list.printList();
//reverse the list
list.reverse();
list.printList();
//print the list to the output file
string outputFile = "hw2_Q1_output.txt"; // the output file
list.printListToFile(outputFile);
return 0;
}
在这种情况下,编译器过于小心 - 它警告您,程序中可能存在一条路径,其中previousNodePtr
未设置为值。
当您检查head
与值匹配并更早返回时,您将始终至少执行一次循环,因此将始终设置previousNodePtr
。
解决此问题的一种方法是在声明时将previousNodePtr
设置为 NULL,这将消除警告。
更好的方法是意识到您不需要在循环中再次针对head
节点进行测试。然后,您可以执行以下操作:
...
else
{
ListNode *previousNodePtr = head;
nodePtr = head->next;
while (nodePtr != NULL && nodePtr->value != x)
{
previousNodePtr = nodePtr;
nodePtr = nodePtr->next;
}
if (nodePtr)
{
previousNodePtr->next = nodePtr->next;
delete nodePtr;
}
另请注意,我将previousNodePtr
声明移近使用位置。
相关文章:
- 为什么我的删除节点函数实际上没有删除节点?
- 我们可以删除链表中静态内存中的节点吗
- 为什么"delete"关键字不删除节点?
- 为什么我的双向链表删除函数会删除多个节点?
- 编写一个函数来删除单链表中的节点(尾部除外),仅授予对该节点的访问权限
- 删除 XML 文件中的子节点C++
- 创建了一个链表,但如何删除 c++ 中的"所有"节点
- 从unordered_map中删除单个节点
- 删除链表中的特定节点
- 在C++中删除双向链表的头节点后出现访问冲突异常
- 删除链表中的节点 - 分段错误
- 删除链接列表中剩余的最后一个节点
- 避免在使用链接列表从 deque 中删除最后一个节点时出现内存泄漏
- 使用函数引用指向节点的指针删除链表中的节点?
- 双向链表 - 无法删除第一个节点
- 双向链表 std::unique_ptr 类在节点删除时无法按预期工作
- BST 节点删除 - 指针未正确删除
- 节点删除功能的链表问题
- 布尔函数始终为真,单向链表中的尾节点删除创建无限循环
- AVL树中节点删除值异常