链表find函数指针无法保存节点地址及函数指针赋值方法咨询
解决链表find函数指针参数始终为nullptr的问题
嘿,我仔细看了你的代码,问题核心出在find函数的逻辑设计偏差上,它并没有实现你想要的「查找元素是否存在」的功能,反而导致指针参数的行为完全不符合预期。咱们一步步拆解问题:
问题根源分析
先看你当前的find函数:
bool find(T x, simpleNode<T>*& p) { p = head; while (p && comparator(p->data, x)) p = p->next; return p?true:false; }
这个函数的逻辑是:从head开始遍历,只要当前节点存在且comparator(p->data, x)为真,就继续往后走。循环结束后直接返回p是否不为空。
这里有两个致命问题:
- 没有判断找到的节点是否等于目标值x:假设你用
less<T>作为比较器维持升序链表,当查找不存在的元素4(链表是1->3->5)时,循环会停在5这个节点(因为less(5,4)为false),此时find返回true,但5≠4,这会导致insert函数错误地认为元素已存在,拒绝插入。 - 只有当x比所有元素都大时,ptr才会变成nullptr:遍历完所有节点后p会变成nullptr,find返回false,这就是你遇到「指针始终为nullptr」的场景——但这只是极端情况,更多时候find的返回结果和指针指向都是错误的。
换句话说,你的find函数根本不是在「查找x是否存在」,而是在「找第一个不满足comparator条件的节点」,完全偏离了你的需求。
修复方案
我们需要修改find函数,让它:
- 正确判断x是否存在于链表中
- 当x不存在时,让ptr指向应该插入的位置(或其前驱节点),维持链表有序
方案1:新增前驱指针(更清晰)
修改后的find函数,新增prev指针记录当前节点的前驱,方便后续插入:
bool find(T x, simpleNode<T>*& p, simpleNode<T>*& prev) { prev = nullptr; p = head; while (p && comparator(p->data, x)) { prev = p; p = p->next; } // 循环结束后,p要么是nullptr,要么是第一个不小于x的节点 // 此时判断p的data是否等于x,才是真正找到目标 return (p != nullptr && p->data == x); }
然后适配insert函数:
bool insert(T x) { simpleNode<T>* currPtr; simpleNode<T>* prevPtr; if (find(x, currPtr, prevPtr)) { // 元素已存在,直接返回false return false; } simpleNode<T>* newNode = new simpleNode<T>(x); if (prevPtr == nullptr) { // 插入到头部(链表为空,或x比所有元素都小) newNode->next = head; head = newNode; } else { // 插入到prevPtr和currPtr之间 newNode->next = currPtr; prevPtr->next = newNode; } return true; }
方案2:不新增前驱指针(紧凑版)
如果不想加prev指针,也可以调整find逻辑,让它停在插入位置的前驱节点:
bool find(T x, simpleNode<T>*& p) { p = nullptr; simpleNode<T>* curr = head; while (curr && comparator(curr->data, x)) { p = curr; curr = curr->next; } // 判断是否找到目标元素 if (curr && curr->data == x) { p = curr; // 找到时让p指向目标节点 return true; } // 没找到时,p指向插入位置的前驱节点 return false; }
对应的insert函数修改:
bool insert(T x) { simpleNode<T>* ptr; if (find(x, ptr)) { return false; } simpleNode<T>* newNode = new simpleNode<T>(x); if (ptr == nullptr) { // 插入头部 newNode->next = head; head = newNode; } else { // 插入到ptr之后 newNode->next = ptr->next; ptr->next = newNode; } return true; }
测试验证
用int类型和less<int>测试:
int main() { simpleLinkedListOnePointer<int, less<int>> list; list.insert(3); list.insert(1); list.insert(5); list.insert(4); list.print(); // 输出:1->3->4->5-> return 0; }
修改后,find函数的指针参数就能正确指向对应节点,不会再出现始终为nullptr的问题。
内容的提问来源于stack exchange,提问作者Armando Miguel Zegarra Castill
相关产品推荐
相关产品推荐

