链表删除仅部分位置生效问题求助(HackerRank题目)
单链表删除节点问题排查
我在解决HackerRank的单链表删除节点题目,要求删除指定位置的节点并返回头节点(头节点位置为0)。编写的C++代码仅对位置0和1的删除操作有效,其他位置均无法正常执行,请求帮忙排查问题。
问题代码(deleteNode函数)
SinglyLinkedListNode* deleteNode(SinglyLinkedListNode* llist, int position) { SinglyLinkedListNode* temp; SinglyLinkedListNode* head =llist; SinglyLinkedListNode* prev = nullptr; int i = 0; if(position == 0){ temp = llist->next; llist = temp; return llist; } else{ while(i<position){ prev = head; head = llist->next; ++i; } temp = head->next; prev->next = temp; return llist; } }
完整代码
#include <bits/stdc++.h> using namespace std; string ltrim(const string &); string rtrim(const string &); class SinglyLinkedListNode { public: int data; SinglyLinkedListNode *next; SinglyLinkedListNode(int node_data) { this->data = node_data; this->next = nullptr; } }; class SinglyLinkedList { public: SinglyLinkedListNode *head; SinglyLinkedListNode *tail; SinglyLinkedList() { this->head = nullptr; this->tail = nullptr; } void insert_node(int node_data) { SinglyLinkedListNode* node = new SinglyLinkedListNode(node_data); if (!this->head) { this->head = node; } else { this->tail->next = node; } this->tail = node; } }; void print_singly_linked_list(SinglyLinkedListNode* node, string sep, ofstream& fout) { while (node) { fout << node->data; node = node->next; if (node) { fout << sep; } } } /* * Complete the 'deleteNode' function below. * * The function is expected to return an INTEGER_SINGLY_LINKED_LIST. * The function accepts following parameters: * 1. INTEGER_SINGLY_LINKED_LIST llist * 2. INTEGER position */ /* * For your reference: * * SinglyLinkedListNode { * int data; * SinglyLinkedListNode* next; * }; * */ SinglyLinkedListNode* deleteNode(SinglyLinkedListNode* llist, int position) { SinglyLinkedListNode* temp; SinglyLinkedListNode* head =llist; SinglyLinkedListNode* prev = nullptr; int i = 0; if(position == 0){ temp = llist->next; llist = temp; return llist; } else{ while(i<position){ prev = head; head = llist->next; ++i; } temp = head->next; prev->next = temp; return llist; } } int main() { ofstream fout(getenv("OUTPUT_PATH")); SinglyLinkedList* llist = new SinglyLinkedList(); string llist_count_temp; getline(cin, llist_count_temp); int llist_count = stoi(ltrim(rtrim(llist_count_temp))); for (int i = 0; i < llist_count; i++) { string llist_item_temp; getline(cin, llist_item_temp); int llist_item = stoi(ltrim(rtrim(llist_item_temp))); llist->insert_node(llist_item); } string position_temp; getline(cin, position_temp); int position = stoi(ltrim(rtrim(position_temp))); SinglyLinkedListNode* llist1 = deleteNode(llist->head, position); print_singly_linked_list(llist1, " ", fout); fout << "\n"; fout.close(); return 0; } string ltrim(const string &str) { string s(str); s.erase( s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace))) ); return s; } string rtrim(const string &str) { string s(str); s.erase( find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(), s.end() ); return s; }
问题分析与修复
问题根源
在else分支的循环中,head = llist->next存在逻辑错误:每次循环都取原链表头节点的下一个节点,而非当前head指针的下一个节点。这导致当position大于1时,head指针无法正确遍历到目标位置,始终停留在原链表第二个节点的位置,最终无法正确删除目标节点。
比如position=2时,循环执行两次:
- 第一次循环:
prev指向原头节点,head指向原头节点的下一个节点 - 第二次循环:
prev指向原头节点的下一个节点,但head仍然指向原头节点的下一个节点(因为llist始终是原头节点)
最终操作的节点并非position=2的节点,导致删除失败。
修复后的deleteNode函数
SinglyLinkedListNode* deleteNode(SinglyLinkedListNode* llist, int position) { SinglyLinkedListNode* temp; SinglyLinkedListNode* current = llist; SinglyLinkedListNode* prev = nullptr; int i = 0; if(position == 0){ return llist->next; } else{ while(i < position){ prev = current; current = current->next; ++i; } temp = current->next; prev->next = temp; return llist; } }
修复说明
- 将变量
head重命名为current,语义更清晰,表示当前遍历的节点 - 将
head = llist->next修改为current = current->next,确保每次循环current指针向后移动一个节点,正确遍历到目标位置 - 删除头节点的逻辑简化为直接返回
llist->next,效果一致且更简洁 - 非头节点删除后返回原头节点
llist,符合题目要求
内容的提问来源于stack exchange,提问作者gratus richard
相关产品推荐
相关产品推荐

