PTA 奇数值结点链表

本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表。链表结点定义如下:

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

这里第二个函数传过来的是一个二级指针,指向指针的指针所以原链表头指针其实是*L,并不是**L这个得搞清楚。
多级指针分析图
多级指针实验代码

#include<stdio.h>

int main(void)
{
	int n = 10;
	int* p = &n;
	int** pp = &p;
	int*** ppp = &pp;
	printf("n = %d\n", n);
	printf("&n = %p\n", &n);
	printf("p = %p\n", p);
	printf("&p = %p\n", &p);
	printf("*p = %d\n", *p);
	printf("pp = %p\n", pp);
	printf("&pp = %p\n", &pp);
	printf("*pp = %p\n", *pp);
	printf("**pp = %d\n", **pp);
	printf("ppp = %p\n", ppp);
	printf("&ppp = %p\n", &ppp);
	printf("*ppp = %p\n", *ppp);
	printf("**ppp = %p\n", **ppp);
	printf("***ppp = %d\n", ***ppp);

	return 0;
}

输出结果
多级指针实验代码输出结果

AC代码(C语言)

struct ListNode* readlist()//创建链表
{
	int data;
	struct ListNode* head = NULL;
	struct ListNode* prev = NULL, * current;
	while (scanf("%d", &data) && data != -1)//读入-1时输入结束
	{
		current = (struct ListNode*)malloc(sizeof(struct ListNode));
		if (head == NULL)
			head = current;
		else
			prev->next = current;
		current->next = NULL;
		current->data = data;
		prev = current;
	}
	return head;
}
struct ListNode* getodd(struct ListNode** L)
{
	struct ListNode* newhead = NULL, * newcurrent = NULL, * newprve = NULL;//用于创建新链表
	struct ListNode* newL = *L;//保存原始链表的表头
	struct ListNode* kill = NULLstruct ListNode* prve = (*L);//初始化为原始链表的表头,用于删除节点
	while (*L)//遍历原始链表
	{
		if ((*L)->data % 2 == 1)
		{
			/*遇到存储的数据为奇数的链表就提取出来创建一个新的链表存储,
			然后删除原始链表中存储该数据的节点。*/
			newcurrent = (struct ListNode*)malloc(sizeof(struct ListNode));
			if (newhead == NULL)
				newhead = newcurrent;
			else
				newprve->next = newcurrent;
			newcurrent->data = (*L)->data;
			newcurrent->next = NULL;
			newprve = newcurrent;
			if ((*L) == newL)//被删节点是链表头
				newL = newL->next;
			else
				prve->next = (*L)->next;//删除节点
			kill = (*L);
			(*L) = (*L)->next;		
			free(kill);//释放内存
		}
		else
		{
			prve = (*L);
			(*L) = (*L)->next;
		}		
	}
	*L = newL;//L中存储的地址改为删除了奇数值结点后的链表的头结点地址
	return newhead;
}
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐