C语言程序设计第五版谭浩强课后答案 第九章习题答案

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.建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删去。
    • C语言程序设计第五版谭浩强更多答案

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第1张图片

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

解题思路及答案:

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

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;
    //如果包含闰年的二月,天数加1
    if(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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第2张图片

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

#include 

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;
	//如果包含闰年的二月,天数加1
	if (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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第3张图片

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

#include 

#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]);
	}
}

运行截图

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第4张图片

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

#include 

#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]);
	}
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第5张图片

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

#include 

#define NAMLEN 20
#define STUCNT 10

typedef 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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第6张图片

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

解题思路及答案:

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

#include 
#define NUM 13
typedef 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置为0
			printf("第 %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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第7张图片

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

解题思路及答案:

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

#include 
#include 

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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第8张图片

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

#include 
#include 

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  ---> next
	newNode->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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第9张图片

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

#include 
#include 
#define COUNT 5
typedef 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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第10张图片

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

解题思路及答案:

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

#include 
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;
}

运行截图:

C语言程序设计第五版谭浩强课后答案 第九章习题答案_第11张图片

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

解题思路及答案:

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

#include 
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 链表的头等于b
		if (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;
}

运行截图:
C语言程序设计第五版谭浩强课后答案 第九章习题答案_第12张图片

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

#include 
#include 
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语言程序设计第五版谭浩强课后答案 第九章习题答案_第13张图片

C语言程序设计第五版谭浩强更多答案

[C语言程序设计第五版谭浩强课后答案 第八章习题答案]
(https://blog.csdn.net/gjggj/article/details/106998697)

你可能感兴趣的:(C语言程序设计第五版,谭浩强,答案)