本题要求实现两个函数

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;
}

/* 你的代码将被嵌在这里 */

struct ListNode *readlist()
{
    struct ListNode *head,*tail,*p;
    int number;
    
    head=tail=NULL;
    do{
        scanf("%d",&number);
        if (number!=-1)
        {
            p=(struct ListNode*)malloc(sizeof(struct ListNode));
            p->data=number;
            p->next=NULL;
            if (head==NULL)
            {
                head=tail=p;
            }
            else {
                tail->next=p;
                tail=p;
            }
        }
    }while(number!=-1);
    return head;
}

struct ListNode *getodd( struct ListNode **L )
{
    struct ListNode *p,*q=NULL,*head=NULL,*tail=NULL;
    
    for (p=*L;p;p=p->next)
    {
        if (p->data%2==1)
        {
            if (head==NULL)
            {
                head=tail=p;
            }
            else {
                tail->next=p;
                tail=p;
            }
            if (q==NULL)
            {
                *L=p->next;
            }
            else {
                q->next=p->next;
            }
        }
        else {
            q=p;
        }
    }
    return head;
}

 

我的问题:当输入的头尾都是偶数时奇链表的输出是错的。。为什么??

struct ListNode *getodd( struct ListNode **L )
{
    struct ListNode *p,*q=NULL,*head=NULL,*tail=NULL, *temp;

    for (p=*L,*L = NULL;p;p=temp)
    {
        temp = p->next;
        if (p->data%2==1)
        {
            if (head==NULL)
            {
                head=tail=p;
            }
            else {
                tail->next=p;
                tail=p;
                tail->next = NULL;
            }
        }
        else {
            if (q==NULL)
            {
                q = *L = p;
            }
            else {
                q->next=p;
                q = q->next;
                q->next = NULL;
            }
        }
    }
    return head;
}

这次没问题啦,这个结果是我在main里面自己加了个while可以测多组数据。NULL表示链表为空,也是我自己加的。

总之,这次的 getodd 没有问题啦

当然会出错了。你在for循环里面判断if(p->data%2==1)的时候,如果是偶数,且第一个就是偶数,那么你的head就是空,没有if (head==NULL)的讨论

struct ListNode *getodd( struct ListNode **L )
{
    struct ListNode *p,*q=NULL,*head=NULL,*tail=NULL;

    for (p=*L;p;p=p->next)
    {
        if (p->data%2==1)
        {
            if (head==NULL)
            {
                head=tail=p;
            }
            else {
                tail->next=p;
                tail=p;
            }
        }
        else {
            if (q==NULL)
            {
                q = *L = p;
            }
            else {
                q->next=p;
                q = q->next;
            }
        }
    }
    tail->next = NULL;
    q->next = NULL;
    return head;
}

现在没有问题了。我把for里面的内容修改了一些。

最后加入了 tail->next = NULL;    q->next = NULL;是为了让链表停下,而不会继续往后走。(如果不这样写,最后的节点就都依附在两条链表的最后)