如何简化链表插入逻辑:新增节点时无需遍历链表的while循环
链表尾插优化方案
你的修改代码错误原因
你写的else分支逻辑存在两个问题:
- 执行
ptr->link = temp后,又执行ptr->link = ptr->link->link,此时ptr->link->link就是你刚赋值的temp的link,也就是NULL,相当于刚把新节点连上就立刻断开,新节点直接丢失 - 没有将尾指针ptr移动到新的尾节点,下次插入时还是在旧的尾节点位置操作,最终链表只会保留第一个节点
正确优化方案
你要的无循环尾插逻辑核心是维护一个永远指向链表最后一个节点的尾指针,不需要每次遍历找末尾,时间复杂度从原来的O(n²)降低到O(n),正确的代码修改如下:
struct node { int data; struct node *link; } *head = NULL, *tail = NULL, *temp = NULL; int main() { // ----- 其他代码逻辑不变 ----- for (i = 0; i < n ; ++i) { temp = malloc(sizeof(struct node)); fscanf(fptr, "%d", &(temp->data)); temp->link = NULL; if (head == NULL) { // 第一个节点,头指针和尾指针都指向它 head = temp; tail = temp; } else { // 直接把新节点挂到当前尾节点后面 tail->link = temp; // 尾指针移动到新的尾节点 tail = temp; } } // ----- 其他代码逻辑不变 ----- }
逻辑说明
- 插入第一个节点时,头指针
head和尾指针tail同时指向这个新节点,保证尾指针初始就落在链表末尾 - 插入后续节点时,直接操作尾指针挂载新节点,再更新尾指针为新节点即可,全程不需要遍历链表
- 注意所有新节点的
link都提前赋值为NULL,保证链表最后一个节点的指针始终为空,符合链表的结构约定
注意:建议对
malloc的返回值做非空校验,避免内存申请失败时触发空指针访问异常;同时使用完链表后要遍历释放所有节点的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者neversettle evolve
相关产品推荐
相关产品推荐

