游客 Signup | Login
中文 | En

1267 - C语言11.3

建立一个存储学生学号和成绩信息的动态链表,并参照本书例题11.8至11.11,实现这个动态链表的建立、输出、删除特定节点、插入操作。

结构体student,存储学生的学号、名字、性别和年龄,读入每个学生的所有信息,保存在结构体中,并输出。
动态链表的每个节点存储的结构体student的定义如下:
struct student {
    long num;
    float score;
    struct student * next;
};

本题较为复杂,请参考本书相应的例题进行实现。

Input

输入的前几行为链表的建立过程。每行有一个整数和一个实数,用空格隔开,分别表示学生的学号和成绩。如果读入的学号为0,说明链表的建立过程已经结束,这个学号为0的信息不存入链表。

之后的几行每行包含一个整数,表示删除学号与这个整数相等的学生信息(删除链表节点)。如果输入的整数为0,说明删除过程已经结束,且不需要处理学号为0的节点。
最后的几行每行包含一个整数和一个实数,用空格隔开,分别表示需要插入的学生学号和成绩。如果读入的学号为0,说明插入的过程已经结束,这个学号为0的信息不需要插入链表。
输入保证在任何时刻,链表中不存在有相同学号的学生,建立链表的过程中输入的学号数值保证严格递增且大于0,链表为空时不会再继续删除。输入的总行数不超过100。

Output

首先规定用以下格式输出某一时刻链表的状态:

在一行内输出当前链表的节点数n,并在接下来的n行中按顺序输出每一个节点(学生)的学号和成绩信息,用空格隔开,且成绩保留1位小数。
在链表的建立过程结束之后,输出当前链表状态;在每一次删除操作(不包括用来标记删除过程结束的学号为0的那一次)之后,输出链表状态;在每一次插入操作(不包括用来标记插入过程结束的学号为0的那一次)之后,输出链表状态。
请注意行尾输出换行。

Examples

Input

10101 90
10103 87
10105 77
0 0
10103
10105
0
10104 87
10106 65
0 0

Output

3
10101 90.0
10103 87.0
10105 77.0
2
10101 90.0
10105 77.0
1
10101 90.0
2
10101 90.0
10104 87.0
3
10101 90.0
10104 87.0
10106 65.0

Solution C

#include <stdio.h>
#include <stdlib.h>
/* 结构体定义 */
struct student {
	long num;
	float score;
	struct student * next;
};
/* n是全局变量,表示当前动态链表的节点个数 */
int n;
/* 定义建立动态链表的函数,返回值为指向链表头的指针 */
struct student * create(void) {
	struct student * head, *tail, *p;
	n = 0;
	head = NULL;
	tail = p = (struct student *)malloc(sizeof(struct student));
	scanf("%ld %f", &p->num, &p->score);
	while (p->num != 0) {
		n++;
		if (n == 1)
			head = p;
		else
			tail->next = p;
		tail = p;
		p = (struct student *)malloc(sizeof(struct student));
		scanf("%ld %f", &p->num, &p->score);
	}
	tail->next = NULL;
	free(p);
	return head;
}
/* 定义输出链表的函数 */
void print(struct student * head) {
	struct student * p;
	p = head;
	printf("%d\n", n);
	while (p != NULL) {
		printf("%ld %.1f\n", p->num, p->score);
		p = p->next;
	}
}
/* 定义删除特定学号节点的函数,返回值为指向链表头的指针 */
struct student * del(struct student * head, long num) {
	struct student *p1, *p2;
	if (head == NULL)
		return head;
	p1 = head;
	/* 如果p1指向的不是要找的节点且后面还有节点,则p1后移 */
	while (p1->num != num && p1->next != NULL) {
		p2 = p1;
		p1 = p1->next;
	}
	/* 找到了需要的节点 */
	if (num == p1->num) {
		/* 如果需要的节点是首节点,则首节点后移;
		否则将下一节点的地址复制给前一节点的next */
		if (p1 == head)
			head = p1->next;
		else
			p2->next = p1->next;
		free(p1);
		n--;
	}
	return head;
}
/* 定义插入节点的函数,返回值为指向链表头的指针 */
struct student * insert(struct student * head, struct student * stud) {
	struct student *p1, *p2;
	p1 = head;
	/* 若原来的链表是空的,则使插入的节点为头节点 */
	if (head == NULL) {
		head = stud;
		head->next = NULL;
	} else {
		/* 如果p1指向的节点学号小于要插入的且后面还有节点,则p1后移 */
		while (p1->num < stud->num && p1->next != NULL) {
			p2 = p1;
			p1 = p1->next;
		}
		/* 新节点要插入在p1之前 */
		if (p1->num > stud->num) {
			/* 需要插入在头结点之前的特殊情况 */
			if (p1 == head) {
				head = stud;
				head->next = p1;
			} else {
				p2->next = stud;
				stud->next = p1;
			}
		} else {
			/* 新节点要插入在p1之后 */
			p1->next = stud;
			stud->next = NULL;
		}
	}
	n++;
	return head;
}
/* 主函数 */
int main() {
	struct student *head, *stud;
	long num_to_del;
	head = create();
	print(head);
	scanf("%ld", &num_to_del);
	while (num_to_del != 0) {
		head = del(head, num_to_del);
		print(head);
		scanf("%ld", &num_to_del);
	}
	stud = (struct student *)malloc(sizeof(struct student));
	scanf("%ld %f", &stud->num, &stud->score);
	while (stud->num != 0) {
		head = insert(head, stud);
		print(head);
		stud = (struct student *)malloc(sizeof(struct student));
		scanf("%ld %f", &stud->num, &stud->score);
	}
	free(stud);
	return 0;
}

Solution C++

#include <stdio.h>
#include <stdlib.h>
/* 结构体定义 */
struct student {
	long num;
	float score;
	struct student * next;
};
/* n是全局变量,表示当前动态链表的节点个数 */
int n;
/* 定义建立动态链表的函数,返回值为指向链表头的指针 */
struct student * create(void) {
	struct student * head, *tail, *p;
	n = 0;
	head = NULL;
	tail = p = (struct student *)malloc(sizeof(struct student));
	scanf("%ld %f", &p->num, &p->score);
	while (p->num != 0) {
		n++;
		if (n == 1)
			head = p;
		else
			tail->next = p;
		tail = p;
		p = (struct student *)malloc(sizeof(struct student));
		scanf("%ld %f", &p->num, &p->score);
	}
	tail->next = NULL;
	free(p);
	return head;
}
/* 定义输出链表的函数 */
void print(struct student * head) {
	struct student * p;
	p = head;
	printf("%d\n", n);
	while (p != NULL) {
		printf("%ld %.1f\n", p->num, p->score);
		p = p->next;
	}
}
/* 定义删除特定学号节点的函数,返回值为指向链表头的指针 */
struct student * del(struct student * head, long num) {
	struct student *p1, *p2;
	if (head == NULL)
		return head;
	p1 = head;
	/* 如果p1指向的不是要找的节点且后面还有节点,则p1后移 */
	while (p1->num != num && p1->next != NULL) {
		p2 = p1;
		p1 = p1->next;
	}
	/* 找到了需要的节点 */
	if (num == p1->num) {
		/* 如果需要的节点是首节点,则首节点后移;
		否则将下一节点的地址复制给前一节点的next */
		if (p1 == head)
			head = p1->next;
		else
			p2->next = p1->next;
		free(p1);
		n--;
	}
	return head;
}
/* 定义插入节点的函数,返回值为指向链表头的指针 */
struct student * insert(struct student * head, struct student * stud) {
	struct student *p1, *p2;
	p1 = head;
	/* 若原来的链表是空的,则使插入的节点为头节点 */
	if (head == NULL) {
		head = stud;
		head->next = NULL;
	} else {
		/* 如果p1指向的节点学号小于要插入的且后面还有节点,则p1后移 */
		while (p1->num < stud->num && p1->next != NULL) {
			p2 = p1;
			p1 = p1->next;
		}
		/* 新节点要插入在p1之前 */
		if (p1->num > stud->num) {
			/* 需要插入在头结点之前的特殊情况 */
			if (p1 == head) {
				head = stud;
				head->next = p1;
			} else {
				p2->next = stud;
				stud->next = p1;
			}
		} else {
			/* 新节点要插入在p1之后 */
			p1->next = stud;
			stud->next = NULL;
		}
	}
	n++;
	return head;
}
/* 主函数 */
int main() {
	struct student *head, *stud;
	long num_to_del;
	head = create();
	print(head);
	scanf("%ld", &num_to_del);
	while (num_to_del != 0) {
		head = del(head, num_to_del);
		print(head);
		scanf("%ld", &num_to_del);
	}
	stud = (struct student *)malloc(sizeof(struct student));
	scanf("%ld %f", &stud->num, &stud->score);
	while (stud->num != 0) {
		head = insert(head, stud);
		print(head);
		stud = (struct student *)malloc(sizeof(struct student));
		scanf("%ld %f", &stud->num, &stud->score);
	}
	free(stud);
	return 0;
}

Time Limit 1 second
Memory Limit 32 MB
Discuss Stats
上一题 下一题