【c语言篇】每日一题-pta-实验11-2-6 奇数值结点链表

题目如下:

裁判测试程序样例:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值