题目描述:
struct Node{ int data; struct Node *next; }
编程实现:输入一个正整数 n (0<n<10),做 n 次下列运算: 输入若干个正整数(输入-1为结束标志),建立一个单向链表,将其中的奇数值结点删除后输出,若删除后链表为空则输出NULL。
输入描述:
第一行一个正整数n表示有n组数据;
接下来n行,每一行输入若干个整数以-1位结束标志(-1不属于序列)
输出描述:
输出删除奇数值结点后的链表
样例输入1:
2
1 2 3 4 5 6 7 -1
1 3 5 6 -1
样例输出1:
2 4 6
6
样例输入2:
3
1 1 1 1 1 -1
2 2 2 2 2 -1
2 3 3 1 3 -1
样例输出2:
NULL
2 2 2 2 2
2
样例输入3:
4
1 1 1 -1
3 3 3 -1
1 3 5 7 9 -1
9 -1
样例输出3:
NULL
NULL
NULL
NULL
注意:链表相关的题避免不了链表创建,有时还需要链表的删除,所以为了提高效率建议自定义链表创建函数以及链表删除函数,本题需要创建多个链表,创建链表函数更是必不可少的。以上两个函数会单独放在最后,不通用每一个题,但思路基本是一致的,稍作修改即万能。
代码实现:
#include<stdio.h> //0x1dfdb7915d0,0x1dfdb791610,0x1dfdb791650,0x1dfdb791690,0x1dfdb7916d0,0x1dfdb791710,0x1dfdb791750,0x1dfdb791aa0
#include<stdlib.h>
struct Node //创建多个链表
{
int data;
struct Node *next; //一种未考虑到的情况,输入数据全为奇数,则会出现信号S
};
struct Node *creat()
{
struct Node *head=NULL,*p1,*p2;
int i=0;
int j=0;
do
{
p1=(struct Node *)malloc(sizeof(struct Node));
scanf("%d",&p1->data);
if(i==0)
{
p2=head=p1;
}
else
{
p2->next=p1;
p1->next=NULL;
p2=p1;
}
i++;
}while(p1->data!=-1);
return(head);
}
void delete(struct Node *head,int i)
{
struct Node *p=head,*q;
int j=0;
while(p&&j<i-1)
{
p=p->next;
j++;
}
q=p->next;
p->next=q->next;
free(q);
}
int judge(struct Node *head)
{
for(;head!=NULL;) {
if ((head->data) % 2 == 0) {
return 0;
break;
}
else
{
head=head->next;
}
if(head==NULL)
{
return 1;
}
}
}
int main()
{
struct Node *head,*p;
int i,n;
scanf("%d",&n);
for(i=0;i<n;i++) {
int choice;
head = creat();
p = head;
choice = judge(head);
if (choice == 1) {
printf("NULL\n");
continue;
} else {
for (; p != NULL;) { //定义头指针,使其不为奇数
if ((head->data) % 2 != 0) { //question
head = head->next;
} else {
break;
}
}
int k = 0;
p = head;
for (; p != NULL;) {
if ((p->data) % 2 != 0) {
delete(head, k);
p = head;
k = 0;
} else {
p = p->next;
k++;
}
}
p = head;
for (; p != NULL;) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
}
return 0;
}
自定义函数:
1.链表创建函数1
struct Node //创建多个链表
{
int data;
struct Node *next; //一种未考虑到的情况,输入数据全为奇数,则会出现信号S
};
struct Node *creat()
{
struct Node *head=NULL,*p1,*p2;
int i=0;
int j=0;
do
{
p1=(struct Node *)malloc(sizeof(struct Node));
scanf("%d",&p1->data);
if(i==0)
{
p2=head=p1;
}
else
{
p2->next=p1;
p1->next=NULL;
p2=p1;
}
i++;
}while(p1->data!=-1);
return(head);
}
2.链表创建函数2
struct stu /*首先定义结构体类型*/
{
int num;
int age;
struct stu *next;
};
struct stu *creat(int n)
{
struct stu *head=NULL,*p1,*p2;
int i;
for(i=0;i<n;i++)
{
p1=(struct stu *)malloc(struct stu); /*动态分配节点,创建链表函数这一步至关重要*/
scanf("%d%d",&p1->num,&p1->age);
if(i==0)
{
p2=head=p1; /*只有一个节点时,头指针指向p1*/
}
else
{
p2->next=p1; /*尾插法将新节点接到链表末尾*/
p1->next=NULL; /*新节点指针域置为0,表示为尾节点*/
p2=p1; /*p2指向链表尾节点*/
}
return (head); /*函数结束返回链表头指针*/
}
3.链表删除函数
void delete(struct Node *head,int i)
{
struct Node *p=head,*q;
int j=0;
while(p&&j<i-1)
{
p=p->next;
j++;
}
q=p->next;
p->next=q->next;
free(q);
}
4.个人的本题判断函数
int judge(struct Node *head)
{
for(;head!=NULL;) {
if ((head->data) % 2 == 0) {
return 0;
break;
}
else
{
head=head->next;
}
if(head==NULL)
{
return 1;
}
}
}
事发经过:
本身在写这段代码时没有设置judge函数,这样的话输入样例1的数据是可以得到正确答案的,但是没有考虑到数据全为奇数的情况,若输入数据全为奇数,则会出现信号:
SIGSEGV (Segmentation fault)
这是老朋友了,输入全奇数数据后发现了问题然后自定义judge函数后,问题解决。