C語言程序設計第五版譚浩強課後答案 第九章習題答案

C語言程序設計第五版譚浩強第九章答案


在這裏插入圖片描述

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;
    //如果包含閏年的二月,天數加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.寫一個函數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;
	//如果包含閏年的二月,天數加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.編寫一個函數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]);
	}
}

運行截圖

C語言程序設計第五版譚浩強課後答案第三題

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 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.13個人圍成一圈,從第1個人開始順序報號1,2,3。凡報到3者退出圈子。找出最後留在圈子中的人原來的序號。要求用鏈表實現。

解題思路及答案:

創建一個環形鏈表,給鏈表中的每一個節點從1~13編號,然後開始淘汰過程,對於淘汰的節點,序號置爲0,淘汰完成之後,找到序號不爲0的即爲最後留下的。

#include <stdio.h>
#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.在第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;
}

運行截圖:

C語言程序設計第五版譚浩強課後答案第七題答案

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  ---> 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(建立鏈表的函數creat)、例9.10(輸出鏈表的函數print)和本章習題第7題(刪除鏈表中結點的函數del)、第8題(插入結點的函數insert),再編寫一個主函數,先後調用這些函數。用以上5個函數組成一個程序,實現鏈表的建立、輸出、刪除和插入,在主函數中指定需要刪除和插人的結點的數據。

#include <stdio.h>
#include <stdlib.h>
#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.已有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;
}

運行截圖:

C語言程序設計第五版答案

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 鏈表的頭等於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;
}

運行截圖:
譚浩強課後習題答案

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語言程序設計第五版譚浩強課後答案 第八章習題答案]
(https://blog.csdn.net/gjggj/article/details/106998697)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章