本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。链表结点定义如下: struct ListNode { int data; ListNode *next; }; 函数接口定义: struct ListNode *readlist(); struct ListNode *getodd( struct ListNode **L );函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。 函数getodd将单链表L中奇数值的结点分离出来,重新组成一个新的链表。返回指向新链表头结点的指针,同时将L中存储的地址改为删除了奇数值结点后的链表的头结点地址(所以要传入L的指针)。 裁判测试程序样例: #include <stdio.h> #include <stdlib.h> struct ListNode { int data; struct ListNode *next; }; struct ListNode *readlist(); struct ListNode *getodd( struct ListNode **L ); void printlist( struct ListNode *L ) { struct ListNode *p = L; while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); } int main() { struct ListNode *L, *Odd; L = readlist(); Odd = getodd(&L); printlist(Odd); printlist(L); return 0; } /* 你的代码将被嵌在这里 */输入样例: 1 2 2 3 4 5 6 7 -1 输出样例: 1 3 5 7 2 2 4 6 下面代码有什么问题struct ListNode *readlist() { int n; struct ListNode *h=NULL,*t,*p; while(1) { scanf("%d",&n); if(n==-1) break; p=(struct ListNode *)malloc(sizeof(struct ListNode)); p->next=NULL; p->data=n; if(h==NULL) { h=p; t=p; } else { t->next=p; t=p; } } return h; }
时间: 2025-03-24 20:14:43 浏览: 44
您提供的`readlist()`函数本身没有明显的问题,它的功能是从标准输入读取一系列正整数,并按顺序构建单链表。然而在完整实现题目需求时,还需要关注`getodd()`函数的设计以及整体逻辑的一致性。
下面是对这两个函数的具体分析:
### `readlist()`
此部分已给出的代码可以正常工作,它会创建一个包含所有非负一数字节点组成的单向链接列表。每次循环迭代都会分配新的内存空间用于存放当前读取到的数据项并将它们串接起来形成最终的结果。
```c
// 已经正确的实现了 readlist 函数.
```
接下来是关于`getodd(struct ListNode **L)` 的说明和示例实现:
---
### 实现 `getodd(struct ListNode **)`
这个任务需要我们做两件事情:
1. 把原始链表里的所有奇数值提取出来构建成一个新的链表;
2. 修改原链表使得其中只保留偶数值或者零。
以下是参考解答的一个版本:
```c
struct ListNode* getodd(struct ListNode** L) {
// 如果初始链表为空,则直接返回 NULL 表示无任何奇数存在即可。
if (*L == NULL) return NULL;
struct ListNode dummy_odd; // 创建虚拟头部便于管理新形成的奇数列队。
struct ListNode *tail = &dummy_odd, *current = *L, *prev = NULL, *temp;
while (current != NULL){
temp = current->next; // 先记住下一个位置因为可能移除节点
if ((current->data % 2)==1){
tail -> next = current; // 当前元素属于奇数则添加至结果集里去
tail = current;
if(prev != NULL){
prev->next = current->next;// 调整上一步连接跳过当前的节点保持连续性
}else { // 若刚好开头就是奇数得单独处理这种情况改变*L指针值
*L=current->next;
}
} else { // 偶数情况不需要动只需要更新prev引用方便后续判断
prev = current;
}
current=temp ; // 移动cur继续遍历剩余未审阅项目
}
tail->next=NULL; // 确保结尾明确标记结束状态
return dummy_odd.next; // 返回真正的头结点不是辅助性的那个占位符哦~
}
```
上述解决方案中使用了一个额外的帮助结构“虚设”节点(dummy node),简化了新建链表首部的操作流程,减少了对边界条件复杂度的关注程度。
#### 关键点解释:
- 使用临时变量保存下一节点地址以防丢失;
- 根据是否找到匹配项动态调整主序列与派生序列之间的关系;
- 特殊考虑首个即需剔除的情形以维持原链表的有效起点不变;
希望以上内容对你有所帮助!
阅读全文
相关推荐









