PTA 奇数值结点链表 超详细
·
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 = NULL;
struct 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;
}
更多推荐
所有评论(0)