失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 《C语言程序设计》第五版谭浩强课后答案 第九章《用户自己建立数据类型​》习题答案

《C语言程序设计》第五版谭浩强课后答案 第九章《用户自己建立数据类型​》习题答案

时间:2023-03-20 16:23:02

相关推荐

《C语言程序设计》第五版谭浩强课后答案 第九章《用户自己建立数据类型​》习题答案

第九章《用户自己建立数据类型​》习题答案

1.定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。2.写一个函数days,实现第1 题的计算。由主函数将年、月、日传递给days函数,计算后将日子数传回主函数输出。3.编写一个函数print,打印一个学生的成绩数组,该数组中有5个学生的数据记录,每个记录包括num,name,score[3],用主函数输人这些记录,用print函数输出这些记录。4.在第3题的基础上,编写一个函数input,用来输人5个学生的数据记录。5.有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩,从键盘输人10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。6.13个人围成一圈,从第1个人开始顺序报号1,2,3。凡报到3者退出圈子。找出最后留在圈子中的人原来的序号。要求用链表实现。7.在第9章例9.9和例9.10的基础上,写一个函数del,用来删除动态链表中指定的节点8.写一个函数insert,用来向一个动态链表插入结点9.综合本章例9.9(建立链表的函数creat)、例9.10(输出链表的函数print)和本章习题第7题(删除链表中结点的函数del)、第8题(插入结点的函数insert),再编写一个主函数,先后调用这些函数。用以上5个函数组成一个程序,实现链表的建立、输出、删除和插入,在主函数中指定需要删除和插人的结点的数据。10.已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并, 按学号升序排列。11.有两个链表a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。12.建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。看到这里了,有帮助,记得点赞,评论

正文开始

1.定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题。

解题思路:

用一个日期数组保存每一月的天数,二月的天数记为28天,后面根据输入的时间确定是否是闰年的二月,如果是,天数在加1。

#include <stdio.h>struct Date{int year;int month;int day;};int main(){struct Date date;printf("Please give date: ");scanf("%d%d%d", &date.year, &date.month, &date.day);int Days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int i, days = 0;for (i = 1; i < date.month; i++)days += Days[i];days += date.day;//如果包含闰年的二月,天数加1if(date.month > 2){if (date.year%400 == 0 || (date.year%4 == 0 && date.year%100 != 0)){++days;} }printf("It's day %d in the year.\n", days);return 0;}

运行截图:

2.写一个函数days,实现第1 题的计算。由主函数将年、月、日传递给days函数,计算后将日子数传回主函数输出。

#include <stdio.h>struct Date{int year;int month;int day;};int Days(struct Date date){static int Days[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int i, days = 0;for (i = 1; i < date.month; i++)days += Days[i];days += date.day;//如果包含闰年的二月,天数加1if (date.month > 2){if (date.year % 400 == 0 || (date.year % 4 == 0 && date.year % 100 != 0)){++days;}}return days;}int main(){struct Date date;printf("Please give date: ");scanf("%d%d%d", &date.year, &date.month, &date.day);int days = Days(date);printf("It's day %d in the year.\n", days);return 0;}

运行截图:

3.编写一个函数print,打印一个学生的成绩数组,该数组中有5个学生的数据记录,每个记录包括num,name,score[3],用主函数输人这些记录,用print函数输出这些记录。

#include <stdio.h>#define NAMLEN 20//定义一个student结构体数组,包含5个元素struct student_t{int num;char name[NAMLEN];int score[3];} students[5];void print(struct student_t *stu);int main(){for (int i = 0; i < 5; i++){scanf("%d%s%d%d%d", &students[i].num, students[i].name, &students[i].score[0],&students[i].score[1], &students[i].score[2]);}print(students);return 0;}void print(struct student_t *stu){for (int i = 0; i < 5; i++){printf("%d %s %d %d %d\n", students[i].num, students[i].name, students[i].score[0],students[i].score[1], students[i].score[2]);}}

运行截图

4.在第3题的基础上,编写一个函数input,用来输人5个学生的数据记录。

#include <stdio.h>#define NAMLEN 20//定义一个student结构体数组,包含5个元素struct student_t{int num;char name[NAMLEN];int score[3];} students[5];void print(struct student_t *stu);void input(struct student_t *stu);int main(){input(students);print(students);return 0;}void input(struct student_t *stu){for (int i = 0; i < 5; i++){scanf("%d%s%d%d%d", &students[i].num, students[i].name, &students[i].score[0],&students[i].score[1], &students[i].score[2]);}}void print(struct student_t *stu){for (int i = 0; i < 5; i++){printf("%d %s %d %d %d\n", students[i].num, students[i].name, students[i].score[0],students[i].score[1], students[i].score[2]);}}

运行截图:

5.有10个学生,每个学生的数据包括学号、姓名、3门课程的成绩,从键盘输人10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程成绩、平均分数)。

#include <stdio.h>#define NAMLEN 20#define STUCNT 10typedef struct student_t{int num;char name[NAMLEN];int score[3];} student;int main(){student students[STUCNT];int maxi = 0, maxsum = 0;double aver_0 = 0, aver_1 = 0, aver_2 = 0;for (int i = 0; i < STUCNT; i++){scanf("%d%s%d%d%d", &students[i].num, students[i].name, &students[i].score[0], &students[i].score[1], &students[i].score[2]);int sum = students[i].score[0] + students[i].score[1] + students[i].score[2];if (sum > maxsum){maxsum = sum;maxi = i;}aver_0 += students[i].score[0];aver_1 += students[i].score[1];aver_2 += students[i].score[2];}aver_0 /= STUCNT;aver_1 /= STUCNT;aver_2 /= STUCNT;printf("%lf %lf %lf\n", aver_0, aver_1, aver_2);printf("%d %s %d %d %d %lf\n", students[maxi].num, students[maxi].name, students[maxi].score[0], students[maxi].score[1], students[maxi].score[2],(students[maxi].score[0] + students[maxi].score[1] + students[maxi].score[2]) / 3.0);return 0;}

运行截图:

6.13个人围成一圈,从第1个人开始顺序报号1,2,3。凡报到3者退出圈子。找出最后留在圈子中的人原来的序号。要求用链表实现。

解题思路:

创建一个环形链表,给链表中的每一个节点从1~13编号,然后开始淘汰过程,对于淘汰的节点,序号置为0,淘汰完成之后,找到序号不为0的即为最后留下的。

#include <stdio.h>#define NUM 13typedef struct people{int num;struct people *next;} people;int main(){int count = NUM;people p[NUM];people *head;head = p; //head 指向p[0]//1~13编号for (int i = 0; i < NUM; i++){head->num = i + 1;head->next = &p[i + 1];head = head->next;}//最后一个元素指向第一个元素 , 形成环p[NUM - 1].next = p; int i = 1;head = p;while (count > 1){//跳过已经被淘汰的节点if (head->num == 0){head = head->next;continue;}if (i == 3){//被淘汰的节点,num置为0printf("第 %d 位置被淘汰\n", head->num);head->num = 0;count--;}head = head->next;i++;if (i > 3){i = 1;}}printf("--------------\n");while (head->num == 0){//非0节点即为最后留下的head = head->next;if (head->num != 0){printf("留到最后的是 %d \n", head->num);}}return 0;}

运行截图:

7.在第9章例9.9和例9.10的基础上,写一个函数del,用来删除动态链表中指定的节点

解题思路:

首先创建一个带头的单链表,然后让用户输入需要删除的节点,调用del函数,找到需要删除的节点,把待删除节点的前驱和后继重新链接。

#include <stdio.h>#include <stdlib.h>typedef struct LNode{int num;struct LNode *next;} LNode;//创建含有n个值的节点LNode* creat(int n){LNode *head, *p;head = (LNode *)malloc(sizeof(LNode));p = head; //头节点为0 加上头节点共n + 1个节点head->num = 0;head->next = NULL;for (int i = 1; i <= n; i++){LNode *newNode = (LNode *)malloc(sizeof(LNode));newNode->num = i;newNode->next = NULL;p->next = newNode;p = p->next;}return head;}//删除值为n的节点void del(int n, LNode *head){LNode *pre, *current;pre = head;current = head->next;//从第一个有效节点开始查找待删除节点printf("delete node %d\n", n);while (current != NULL){//找到待删除节点,重新链接,释放待删除节点if (current->num == n){pre->next = current->next;free(current);break;}//更新查找位置pre = current;current = current->next;}}int main(){LNode *head, *p;int n;head = creat(10);printf("请输入需要删除的节点:1-10\n");scanf("%d", &n);del(n, head);int i = 1;p = head->next;while (p != NULL){printf("p %d.num -> %d\n", i, p->num);p = p->next;i++;}return 0;}

运行截图:

8.写一个函数insert,用来向一个动态链表插入结点

#include <stdio.h>#include <stdlib.h>typedef struct LNode{int num;struct LNode *next;} LNode;void insert(int n, LNode *node){//创建新节点LNode *newNode = (LNode *)malloc(sizeof(LNode));newNode->num = n;LNode* next = node->next;// node ---> newNode ---> nextnewNode->next = next;node->next = newNode;}LNode* creat(int n){LNode *head, *p;head = (LNode *)malloc(sizeof(LNode));p = head; //头节点为0 加上头节点共11个节点head->num = 0;head->next = NULL;for (int i = 1; i <= n; i++){LNode *newNode = (LNode *)malloc(sizeof(LNode));newNode->num = i;newNode->next = NULL;p->next = newNode;p = p->next;}return head;}void printNode(LNode* head){LNode* p = head->next;while (p != NULL){printf("num -> %d\n", p->num);p = p->next;}}int main(){LNode *head;int n;head = creat(10);printNode(head);printf("请输入需要插入的节点:\n");scanf("%d", &n);insert(n, head);printf("链表的新内容:\n");printNode(head);return 0;}

运行截图:

9.综合本章例9.9(建立链表的函数creat)、例9.10(输出链表的函数print)和本章习题第7题(删除链表中结点的函数del)、第8题(插入结点的函数insert),再编写一个主函数,先后调用这些函数。用以上5个函数组成一个程序,实现链表的建立、输出、删除和插入,在主函数中指定需要删除和插人的结点的数据。

#include <stdio.h>#include <stdlib.h>#define COUNT 5typedef struct LNode{int num;struct LNode *next;} LNode;LNode* create(int n){LNode *head, *p;head = (LNode *)malloc(sizeof(LNode));p = head; //头节点为0 加上头节点共11个节点head->num = 0;head->next = NULL;for (int i = 1; i <= n; i++){LNode *newNode = (LNode *)malloc(sizeof(LNode));newNode->num = i;newNode->next = NULL;p->next = newNode;p = p->next;}return head;}//在指定位置插入数据void insert(int n, int positon, LNode *root){//首先找到指定位置while (positon--){root = root->next;}//插入新的数据,重新链接插入点的前后节点关系LNode *newNode = (LNode *)malloc(sizeof(LNode));newNode->num = n;newNode->next = root->next;root->next = newNode;}void del(int n, LNode *root){LNode *pre;while (root->num != n){pre = root;root = root->next;}pre->next = root->next;}void printList(LNode *root){printf("----\n");int i = 0;while (root != NULL){printf("node %d -> %d\n", i, root->num);root = root->next;i++;}}int main(){int n, position;printf("请输入插入/删除的数,及插入的位置,位置最大为:%d\n", COUNT);scanf("%d %d", &n, &position);LNode *head = create(COUNT);printList(head->next);insert(n, position, head->next);printList(head->next);del(n, head->next);printList(head->next);return 0;}

运行截图:

10.已有a,b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并, 按学号升序排列。

解题思路:

首先合并两个链表,然后采用选择排序,给合并之后的链表进行排序。

#include <stdio.h>typedef struct student{int num;double grade;struct student *next;} student;student *merge(student *a, student *b){//先合并,后排序student *head = a;while (a->next != NULL){a = a->next;}a->next = b;//选择排序,每次选最小的,放在未排序的链表头部student *pre;pre = head;while (pre->next != NULL){a = pre->next;while (a != NULL){if (pre->num > a->num){int num = pre->num;double grade = pre->grade;pre->num = a->num;pre->grade = a->grade;a->num = num;a->grade = grade;}a = a->next;}pre = pre->next;}return head;}int main(){student a[3] = {{1, 79}, {4, 36}, {5, 79}};for (int i = 0; i < 2; i++){a[i].next = &a[i + 1];}student b[2] = {{2, 38}, {6, 98}};for (int i = 0; i < 1; i++){b[i].next = &b[i + 1];}student *combine = merge(a, b);while (combine != NULL){printf("%d -> %.2lf\n", combine->num, combine->grade);combine = combine->next;}return 0;}

运行截图:

11.有两个链表a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。

解题思路:

对于b链表中的每一个节点,都从a链表的表头开始查找,如果可以找到,直接删除,如果找不到,继续从a链表表头找下一个b的节点。

#include <stdio.h>typedef struct student{int num;double grade;struct student *next;} student;student *del(student *a, student *b){student *pre, *current, *head;head = a;while (b != NULL){//重置指针指向a链表的头部pre = head;current = head->next;//a 链表的头等于bif (pre->num == b->num){pre->next = NULL;pre = current;current = current->next;//更新表头head = pre;}else{while (pre->next != NULL){if (current->num == b->num){//找到就删除pre->next = current->next;break;}else{//否则继续遍历pre = pre->next;current = current->next;}}}b = b->next;}return head;}void printList(student *root){printf("----\n");int i = 0;while (root != NULL){printf("student %d -> %d -> %.2lf\n", i, root->num, root->grade);root = root->next;i++;}}int main(){student a[3] = { { 1, 79 }, { 4, 36 }, { 5, 79 } };for (int i = 0; i < 2; i++){a[i].next = &a[i + 1];}a[2].next = NULL;printf("链表a:\n");printList(&a[0]);student b[2] = { { 5, 38 }, { 4, 98 } };for (int i = 0; i < 1; i++){b[i].next = &b[i + 1];}b[1].next = NULL;printf("链表b:\n");printList(&b[0]);student *combine = del(a, b);printf("删除之后:\n");while (combine != NULL){printf("%d -> %.2lf\n", combine->num, combine->grade);combine = combine->next;}return 0;}

运行截图:

12.建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。

#include <stdio.h>#include <stdio.h>typedef struct student{int num;char sex[10];char name[100];int age;struct student *next;} student;void printList(student *root){printf("----\n");while (root != NULL){printf("num:%d, sex: %s, name: %s, age: %d\n", root->num, root->sex, root->name, root->age);root = root->next;}}int main(){student a[] = { { 1, "woman", "apple", 12 }, { 4, "woman", "banbana", 36 }, { 5, "man", "candy", 79 }, { 5, "man", "danny", 36 }, { 4, "man", "enjoy", 98 } };for (int i = 0; i < 4; i++){a[i].next = &a[i + 1];}a[4].next = NULL;printList(&a[0]);int n;printf("请输入要删除的年龄:\n");scanf("%d", &n);student *pre = a, *current = a->next, *head;head = a;while (current != NULL){//如果头结点需要删除,则更新头结点if (head->age == n){pre->next = NULL;pre = current;current = current->next;head = pre;}else{//删除节点,重新链接if (current->age == n){pre->next = current->next;}pre = current;current = current->next;}}printList(head);return 0;}

运行截图:

看到这里了,有帮助,记得点赞,评论

其他章节:

第一章《程序设计和C语言》习题答案

第二章《算法–程序的灵魂》习题答案

第三章《最简单的C程序设计–顺序程序设计》习题答案

第四章《选择结构程序设计》习题答案

第五章《循环结构程序设计》习题答案

第六章《利用数组处理批量数据》习题答案

第七章《用函数实现模块化程序设计​》习题答案

第八章《善于利用指针​》习题答案

第九章《用户自己建立数据类型​》习题答案

第十章《对文件的输入输出​》习题答案

《C语言程序设计》第五版谭浩强课后答案 第九章《用户自己建立数据类型​》习题答案 (大一大二 考研 计算机二级必看)

如果觉得《《C语言程序设计》第五版谭浩强课后答案 第九章《用户自己建立数据类型​》习题答案》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。