本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。链表结点定义如下:
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
// Odd = getodd(&L); // 取 址 才能传输数据吗?? 是因为getodd 中无L的定义 必须用*L才能从外部数据传输?
// printlist(Odd); //prinlist 是为了输出链表数值重新 定义的函数
struct ListNode *readlist()
{
int data;
struct ListNode *head=NULL; //头节点为空
struct ListNode *p;
while(scanf("%d",&data)&&data!=-1)
{
struct ListNode *q=(struct ListNode*)malloc(sizeof(struct ListNode));
if(q!=NULL)
{
q->data=data;
q->next=NULL;
}
else exit(1); //exit(1)是异常退出,比如你的代码在出现不应该出现的分枝,要求终止程序的时候就用exit(1)
//即 q不应当为空
if(head!=NULL)
{
p->next=q; //增加链表
}
else head=q; //第一次运行while 时 这一步都会做
p=q; //把q的值交给p 使得下一次p->next=q; 起到q1 ->q2->q3->q4 的作用
}
return head; //返回头节点 有了头 就可以输出下面所有的数据
}
struct ListNode *getodd( struct ListNode **L ) //二级指针?
{
struct ListNode *head0=NULL,*head1=NULL,*p0,*p1;
while((*L)!=NULL)
{
int data=(*L)->data;
struct ListNode *q=(struct ListNode*)malloc(sizeof(struct ListNode));
if(data%2)
{
if(q!=NULL)
{
q->data=data;
q->next=NULL;
}
else exit(1);
if(head1!=NULL)
{
p1->next=q;
}
else head1=q;
p1=q; // p1存奇数 head1
} //p0存偶数 head 0
else
{
if(q!=NULL)
{
q->data=data;
q->next=NULL;
}
else exit(1);
if(head0!=NULL)
{
p0->next=q;
}
else head0=q;
p0=q;
}
*L=(*L)->next;
}
*L=head0; //分离结束以后 L 储存偶数的值
return head1; //返回奇数的值
}