C++链表插入节点时如何避免重复ID值问题
问题场景
在C++实现的单链表中存储节点数据,每个节点包含三个字段:
int类型idchar数组类型namechar类型gol(血型)
需求为插入新节点时校验ID唯一性:例如首次输入id=12、name=jon、gol=A后,若再次输入id=12,需弹出Id cant be same提示,阻止重复ID的节点插入。
现有已编写的链表头插法函数tambah_awal_list基础代码存在多处逻辑错误:- 空链表时访问
head指针存在空指针崩溃风险 - 仅对比头节点ID,未遍历全链表做全量ID校验
- 检测到ID重复时仍会执行后续插入流程,无法阻断重复节点写入
需要明确代码修改点,正确实现ID唯一性校验需求。
原有错误实现代码
#include <iostream> #include <string> #include <conio.h> struct node { int id; char name[20], gol; node *next; }; node *head = nullptr; node *tail = nullptr; void tambah_awal_list() { int id; char name[20]; char gol; node *baru = new node; baru->id=head->id; std::cout << "Id : "; std::cin >> baru->id; if (head->id == baru->id){ std::cout << "Id cant be same"<<std::endl; } std::cout << "Name : "; std::cin >> baru->name; std::cout << "Blood type (A/B/O) : "; std::cin >> baru->gol; if(head == nullptr) { head = baru; head->next = nullptr; tail = head; } else { baru->next = head; head = baru; } }
修复修改点说明
- 删除错误的空指针访问逻辑:去掉
baru->id=head->id;语句,空链表下head为nullptr,直接访问head->id会直接触发程序崩溃。 - 调整执行流程顺序:先读取用户输入的新节点ID,再做重复校验,校验通过后再读取姓名、血型字段,减少无效输入场景下的冗余操作。
- 替换错误的单节点对比逻辑:从
head节点开始遍历整个链表,逐个对比已有节点的ID和新输入ID,只要存在匹配项就判定为ID重复。 - 增加重复ID阻断逻辑:检测到ID重复后,先释放提前申请的新节点内存避免内存泄漏,直接输出提示后
return退出函数,不再执行后续插入流程。 - 修正空链表判断的位置:空链表判断必须放在所有访问
head成员的逻辑之前,避免空指针访问。
修复后可运行代码
#include <iostream> #include <string> #include <conio.h> struct node { int id; char name[20], gol; node *next; }; node *head = nullptr; node *tail = nullptr; void tambah_awal_list() { node *baru = new node; std::cout << "Id : "; std::cin >> baru->id; // 全链表遍历校验ID唯一性 node* current = head; bool id_duplicate = false; while (current != nullptr) { if (current->id == baru->id) { id_duplicate = true; break; } current = current->next; } if (id_duplicate) { std::cout << "Id cant be same" << std::endl; delete baru; // 释放已申请的内存避免泄漏 return; // 直接退出,不执行后续插入逻辑 } std::cout << "Name : "; std::cin >> baru->name; std::cout << "Blood type (A/B/O) : "; std::cin >> baru->gol; baru->next = nullptr; if(head == nullptr) { head = baru; tail = head; } else { baru->next = head; head = baru; } }
注:如果需要更严谨的输入校验,可以额外补充血型输入范围判断、char数组输入长度截断逻辑,避免缓冲区溢出。
内容的提问来源于stack exchange,提问作者Xianying
相关产品推荐
相关产品推荐

