C语言链表合并函数故障求助:自定义join函数无法正常工作
链表合并函数故障排查
链表结构定义
typedef int type; typedef struct node{ int val; struct node *next; } node; typedef struct list{ node *head; }listtype ;
(typedef type的作用是只需修改该行即可更改链表的数据类型)
插入函数实现
void insert(listtype *l, type elem, int pos) { node *p = (node*)malloc(sizeof(node)); p->val = elem; if (pos == 0) { p->next = l->head; l->head = p; } else { node *q; int i; for (q = l->head, i = 0; i < pos - 1; i++) { q = q->next; } p->next = q->next; q->next = p; } }
存在问题的合并函数
void list_join(listtype *l,listtype *c) { if (list_empty(*l)) { printf("List empty"); } else { node *q; int i = 0; q = l->head; while (q->next != NULL) { insert(&c ,q->val, i + list_size(*c)); q = q->next; i++; } } }
打印函数实现
void list_view(listtype l) { if (list_empty(l)) printf("List empty"); else { node *q; q = l.head; int i = 0; while (q->next != NULL) { printf("%d \t %d \n", i, q->val); q = q->next; i++; } printf("%d \t %d \n", i, list_tail(l)); } }
问题排查与修复
1. 函数参数类型不匹配
insert函数要求第一个参数为**listtype*类型,但你调用时传入的是&c——c本身已经是listtype*,&c会变成listtype****,类型完全不匹配,直接导致内存操作错误,破坏链表结构。
修复:将insert(&c ,q->val, ...)改为insert(c ,q->val, ...)。
2. 循环遗漏最后一个节点
while (q->next != NULL)的循环条件会跳过原链表的最后一个节点:当q指向最后一个节点时,q->next为NULL,循环终止,该节点的元素不会被插入到目标链表中。
修复:将循环条件改为while (q != NULL),确保遍历所有节点。
3. 插入位置计算冗余且错误
你用i + list_size(*c)作为插入位置,实际上每次只需将元素追加到目标链表c的末尾,直接传入list_size(*c)即可(链表长度就是末尾插入的合法位置)。i作为原链表的节点索引,和目标链表长度相加会导致插入位置越界,破坏链表。
修复:插入位置改为list_size(*c)。
4. 空指针与边界判断优化
原函数未判断l或c是否为NULL,若传入空指针会直接崩溃。同时原逻辑仅判断原链表为空的情况,可补充空指针校验。
修复后的合并函数
void list_join(listtype *l, listtype *c) { if (l == NULL || c == NULL) { printf("Invalid list pointer"); return; } if (list_empty(*l)) { printf("Source list is empty"); return; } node *q = l->head; while (q != NULL) { insert(c, q->val, list_size(*c)); q = q->next; } }
额外注意事项
- 确保
list_size、list_empty、list_tail辅助函数逻辑正确,比如list_size需准确统计节点数量,list_empty需判断head是否为NULL。 insert函数未处理pos超出链表长度的情况,若pos大于当前链表长度,会导致q访问NULL的next指针引发崩溃,可在insert中增加合法性判断,默认将超出范围的pos处理为插入到末尾。
内容的提问来源于stack exchange,提问作者Hatem
相关产品推荐
相关产品推荐

