题目如下:
裁判测试程序样例:
#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;
}
/* 你的代码将被嵌在这里 */
代码如下:
struct ListNode *readlist()
{
//一开始不给head动态分配内存,因为链表可能为空
//分配内存后再为NULL,会使其无效
struct ListNode *head = NULL;
struct ListNode *tail = NULL;
struct ListNode *p;
int n;
scanf("%d",&n);
while(n!=-1)
{
p = (struct ListNode *)malloc(sizeof(struct ListNode));
p->data = n;
p->next = NULL;
//此时我们需要将新结点添加到链表中,添加新结点有两种情况
//如果链表为空,让当前新结点成为链表的第一个结点(之前的链表为空)
if(head == NULL)
{
head = p;
}
//之前的链表不为空,添加到链表的尾部
else{
tail->next = p;
}
//确保tail始终指向链表的末尾
tail = p;
scanf("%d",&n);
}
return head;
}
struct ListNode *getodd( struct ListNode **L )
{
struct ListNode *odd_head = NULL;//表示头结点
struct ListNode *odd_tail = NULL;//表示尾节点
struct ListNode *prev = NULL;//为当前结点之前的结点
struct ListNode *cur = *L;//为当前处理的结点
//遍历输入链表
while(cur)
{
if(cur->data % 2 == 1)//检查时否为奇数
{
//如果当前结点为空
if(odd_head == NULL)
{
odd_head = cur;
}
else{
odd_tail->next = cur;
}
odd_tail = cur;//保证其一直指向链表的末尾
//在新链表中添加了新结点后,需要将当前结点从原链表中删除
//如果当前结点是链表的头结点
if(prev == NULL)
{
//将原始链表头结点更新为下一个结点
*L = cur->next;
}
else{
//将prev的next指针指向当前结点的下一个结点以删除当前契数值结点
prev->next = cur->next;
}
cur = cur->next;//将cur指针移到下一个结点,准备处理下一个结点
odd_tail->next = NULL;
}
//当前结点不为奇数,跳过
else{
prev = cur;
cur = cur->next;
}
}
return odd_head;
}