C语言有序日期单链表插入新节点的if判断逻辑问题排查
代码问题排查
1. 基础语法错误
你定义的node结构体里存储日期的成员名为d,但代码里写的是pnew->p = pn,这里会直接编译失败,需要改成pnew->d = pn。
2. 日期比较逻辑完全错误
你当前的判断逻辑存在根本性偏差:
- 当当前节点年份大于新节点年份时,不管月日如何,当前节点的日期一定晚于新节点,你反而加了月日不等就
continue的逻辑,直接跳过了正确的插入位置 - 同理,年份相等但月份更大时,不管日期如何当前节点日期都更晚,你也加了日期不等就跳过的逻辑,完全不符合日期排序的规则
- 你现在的逻辑只有碰到和新节点日期完全相等、或者日期刚好比新节点大一天的情况才会插入,其他场景都会漏掉插入操作
3. 插入位置逻辑错误
单向链表如果要插入到当前节点i的前面,必须要记录i的前驱节点,否则无法修改前驱的next指针指向新节点。你现在的插入逻辑是把新节点插到i的后面,相当于把比i早的日期插到了i后面,完全打乱了升序排列的规则。
4. 边界场景完全未处理
- 没有处理新节点日期最小、需要插入到表头的场景,这种情况需要更新返回的
head指针 - 没有处理新节点日期最大、需要插入到链表末尾的场景,循环走完后新节点没有被挂载到链表上,还会造成内存泄漏
正确实现参考
// 辅助函数:比较两个日期大小,a < b 返回-1,a == b 返回0,a > b 返回1 int compareDate(date a, date b) { if (a.yy != b.yy) return a.yy > b.yy ? 1 : -1; if (a.mm != b.mm) return a.mm > b.mm ? 1 : -1; if (a.dd != b.dd) return a.dd > b.dd ? 1 : -1; return 0; } node* addNode(date pn, node* head) { // 申请新节点 node* pnew = (node*)malloc(sizeof(node)); if (pnew == NULL) return head; // 增加内存申请失败的判空逻辑 pnew->d = pn; pnew->next = NULL; // 情况1:链表为空,或者新节点比头节点小,直接插在表头 if (head == NULL || compareDate(pnew->d, head->d) < 0) { pnew->next = head; return pnew; } // 情况2:遍历找插入位置,记录前驱节点 node* prev = head; while (prev->next != NULL && compareDate(pnew->d, prev->next->d) >= 0) { prev = prev->next; } // 插入到prev的后面 pnew->next = prev->next; prev->next = pnew; return head; }
如果你的链表是按日期降序排列,仅需要修改compareDate的返回值判断逻辑即可。
内容的提问来源于stack exchange,提问作者xxx
相关产品推荐
相关产品推荐

