S1E45:单链表1 课后作业

news2024/12/26 23:43:50

测试题:
0. 相比起数组来说,单链表具有哪些优势呢?

答:长度非固定,可以申请添加长度

答案:对于数组来说,随机插入或者删除其中间的某一个元素,都是需要大量的移动操作,而单链表则完全没有这个问题。
数组插入图示:

单链表插入图示:


1. 相比起单链表来说,数组又具有哪些优势呢?$

答:简单明了

答案:对于单链表来说,随机访问中间的某一个元素,都是需要大量的跳转操作(从第一个元素开始,然后通过指针一个一个往后跳,最后抵达目标位置),而数组则完全没有这个问题(直接通过下标索引值一步到位地访问)。.E


2. 现在要求编写一个记账小程序,那么你应该考虑使用数组还是单链表来存放数据呢?依据是什么?

答:使用单链表,依据是记账是可持续的,存储长度需要可调节

答案:应该使用单链表比较合适,因为记账小程序要求随时可以从中间位置插入数据,并且具有写入操作多(每天记一记),读取操作少(月底看下总结)的特点,所以选择单链表来实现会更合适。
 

3. 请问下面代码存在什么问题?

struct A
{
        struct B b;
};
    
struct B
{
        struct A a;
}

答:无限嵌套,死循环

答案:还是无限递归。
解析:在 A 结构体声明中定义 B 结构体,但在 B 结构体中又定义 A 结构体。
这就相当于当某人问你和你女朋友什么时候结婚,你们的回复都是“她/他说什么时候就什么时候,我绝对不会告诉你什么时候”酱紫……

4. 本节视频最后的代码演示中小甲鱼在写 releaseLibrary 函数的时候犯了一个比较明显的错误,你能找出来并改正吗?

答:看不出来(错误

答案:

解析:
从逻辑上来说这是矛盾的:既然 library 指向的堆空间已经释放了,那么 library->next 理论上就是一个不存在的值,又何来 library = library->next; 呢?
应该这么改:

void releaseLibrary(struct Book *library)
{
        struct Book *temp;
    
        while (library != NULL)
        {
                temp = library;
                library = library->next;
                free(temp);
        }
}

5. 请问下面代码中,为什么 addBook(struct Book **library) 函数要使用两个星号(**)?

#include <stdio.h>
#include <stdlib.h>
    
struct Book
{
        char title[128];
        char author[40];
        struct Book *next;
};
        
void addBook(struct Book **library)
{
        struct Book *book;
        
        book = (struct Book *)malloc(sizeof(struct Book));
        if (book == NULL)
        {
                printf("内存分配失败了!\n");
                exit(1);
        }
        
        strcpy(book->title, "《零基础入门学习C语言》");
        strcpy(book->author, "小甲鱼");
        
        *library = book;
        book->next = NULL;
}
        
int main(void)
{
        struct Book *library = NULL;
        
        addBook(&library);
        
        return 0;
}

答:不理解(错误

答案:这就是传值和传地的区别啦。
上面代码的内存存储结构如下:

但是,如果你把代码改成下面这样(一个星号):

#include <stdio.h>
#include <stdlib.h>
    
struct Book
{
        char title[128];
        char author[40];
        struct Book *next;
};
        
void addBook(struct Book *library)
{
        struct Book *book;
        
        book = (struct Book *)malloc(sizeof(struct Book));
        if (book == NULL)
        {
                printf("内存分配失败了!\n");
                exit(1);
        }
        
        strcpy(book->title, "《零基础入门学习C语言》");
        strcpy(book->author, "小甲鱼");
        
        *library = book;
        book->next = NULL;
}
        
int main(void)
{
        struct Book *library = NULL;
        
        addBook(library);
        
        return 0;
}

那么,内存的存储结构就会变成:

看出区别来了吗?
addBook(library) 传递的是 library 指针的值,也就是把 NULL 传过去了;而 addBook(&library) 传递的是 library 指针的地址,自然,传过去的是指针的地址,那么要接住它就必须使用指向指针的指针(两个星号)啦~H

动动手:
0. 还记得上一节课后作业吗?
我们帮社区大妈编写了一个打疫苗的登记程序^o^Q
不过,那个只是实验品,因为它只能接受 3 个数据(小李、老王和法外狂徒张三)
这次,我们要求使用单链表来动态存储登记的数据(从堆中申请的空间记得在程序结束前要释放哦~)v
程序实现效果:

答:参考答案解答

#include <stdio.h>
#include <stdlib.h>

struct Date
{
	int year;
	int month;
	int day;
};


struct Record
{
	char name[16];
	int age;
	struct Date first;
	struct Date second;
	struct Record *next;
	
};


void getInput(struct Record *record)
{
	char ch;
	
	printf("请问姓名是:");
	scanf("%s",record->name);
	
	printf("请问年龄是:");
	scanf("%d",&record->age);
	
	printf("请问是否接种过疫苗(Y/N):");
	getchar();
	if(getchar() != 'Y')
	{
		record->first.year = 0;
		printf("请尽快接种疫苗!\n"); 	
	}
	else
	{
		printf("请输入第一针疫苗接种的日期(yyyy-mm-dd):");
		scanf("%d-%d-%d",&record->first.year,&record->first.month,&record->first.day);
	
		printf("请问是否接种第二针疫苗(Y/N):");	
		getchar();
		if(getchar() != 'Y')
		{
			record->first.year = 0;
			printf("请尽快接种第二针疫苗!\n"); 
		}
		else{
			printf("请输入第二针疫苗接种的日期(yyyy-mm-dd):");
			scanf("%d-%d-%d",&record->second.year,&record->second.month,&record->second.day);
		}
	}
	printf("\n");
}


void printRecord(struct Record *head)
{
	struct Record *record;
	
	record = head;
	
	while(record != NULL)
	{
		printf("姓名:%s",record->name);
		printf("年龄:%d\n",record->age);
		if(record->first.year == 1)
		{
			printf("第一针疫苗接种日期:%d-%d-%d\n",record->first.year,
			record->first.month,record->first.day);
			if(record->second.year == 1)
			{
				printf("第一针疫苗接种日期:%d-%d-%d\n",record->second.year,
				record->second.month,record->second.day);
			}
			else
			{
				printf("未接种第二针疫苗!\n"); 
			}
		}
		else
		{
				printf("未接种疫苗!\n"); 
		} 
		record = record->next;
	}
}

void addRecord(struct Record **head)
{
	struct Record *record, *temp;
	
	record = (struct Recoed *)malloc(sizeof(struct Record));
	if(record == NULL)
	{
		printf("内存分配失败\n");
		exit(1); 
	}
	getInput(record);
	
	if(*head != NULL)
	{
		temp = *head;
		*head = record;
		record->next = temp;
	}
	else
	{
		*head = record;
		record->next = NULL;
	}
	
}


void releaseRecord(struct Record *head)
{
	struct Record *temp;
	
	while(head != NULL)
	{
		temp = head;
		head = head->next;
		free(temp);
		
	}
	
}



int main(void)
{
	struct Record *record;
	int i,ch;
	
	while(1)
	{
		printf("是否需要录入(Y/N):");
		do
		{
			ch = getchar();
		}
		while(ch != 'Y' && ch !='N');
		
		if(ch == 'Y')
		{
			addRecord(&record);
		}
		else
		{
			break;
		}
	}
	printf("请问是否需要打印已录入数据(Y/N):");
    do
    {
            ch = getchar();
    } while (ch != 'Y' && ch != 'N');

    if (ch == 'Y')
    {
            printRecord(record);
    }

    releaseRecord(record);

    return 0;
	
	
	
}

 

答案:

#include <stdio.h>
#include <stdlib.h>
    
struct Date
{
        int year;
        int month;
        int day;
};
    
struct Record
{
        char name[16];
        int age;
        struct Date first;
        struct Date second;
        struct Record *next;
};
void getInput(struct Record *record);
void printRecord(struct Record *head);
void addRecord(struct Record **head);
void releaseRecord(struct Record *head);
    
void getInput(struct Record *record)
{
        printf("请问姓名是:");
        scanf("%s", record->name);
        printf("请问年龄是:");
        scanf("%d", &record->age);
        printf("请问是否接种过疫苗(Y/N):");
    
        getchar();
        if (getchar() != 'Y')
        {
                record->first.year = 0;
                printf("请尽快接种疫苗!\n");
        }
        else
        {
                printf("请输入第一针疫苗接种的日期(yyyy-mm-dd):");
                scanf("%d-%d-%d", &record->first.year, &record->first.month, &record->first.day);
    
                printf("请问是否接种第二针疫苗(Y/N):");
                getchar();
                if (getchar() != 'Y')
                {
                        record->second.year = 0;
                        printf("请尽快接种第二针疫苗!\n");
                }
                else
                {
                        printf("请输入第二针疫苗接种的日期(yyyy-mm-dd):");
                        scanf("%d-%d-%d", &record->second.year, &record->second.month, &record->second.day);
                }
        }
        putchar('\n');
}
    
void printRecord(struct Record *head)
{
        struct Record *record;
    
        record = head;
    
        while (record != NULL)
        {
                printf("姓名:%s,年龄:%d\n", (*record).name, (*record).age);
    
                if (record->first.year == 0)
                {
                        printf("未接种疫苗!\n\n");
                }
                else
                {
                        printf("第一针疫苗接种日期:%d-%d-%d,", (*record).first.year, (*record).first.month, (*record).first.day);
                }
    
                if ((*record).first.year != 0 && (*record).second.year == 0)
                {
                        printf("未接种第二针疫苗!\n\n");
                }
                else if((*record).first.year != 0)
                {
                        printf("第二针疫苗接种日期:%d-%d-%d\n\n", (*record).second.year, (*record).second.month, (*record).second.day);
                }
    
                record = record -> next;
        }
}
    
void addRecord(struct Record **head)
{
        struct Record *record, *temp;
    
        record = (struct Record *)malloc(sizeof(struct Record));
        if (record == NULL)
        {
                printf("内存分配失败!\n");
                exit(1);
        }
    
        getInput(record);
    
        if (*head != NULL)
        {
                temp = *head;
                *head = record;
                record->next = temp;
        }
        else
        {
                *head = record;
                record->next = NULL;
        }
}
    
void releaseRecord(struct Record *head)
{
        struct Record *temp;
    
        while (head != NULL)
        {
                temp = head;
                head = head->next;
                free(temp);
        }
}
    
int main(void)
{
        struct Record *head = NULL;
        int ch;
    
        while (1)
        {
                printf("请问是否需要录入(Y/N):");
                do
                {
                        ch = getchar();
                } while (ch != 'Y' && ch != 'N');
    
                if (ch == 'Y')
                {
                        addRecord(&head);
                }
                else
                {
                        break;
                }
        }
    
        printf("请问是否需要打印已录入数据(Y/N):");
        do
        {
                ch = getchar();
        } while (ch != 'Y' && ch != 'N');
    
        if (ch == 'Y')
        {
                printRecord(head);
        }
    
        releaseRecord(head);
    
        return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698059.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于tcp实现自定义应用层协议

认识协议 协议&#xff08;Protocol&#xff09; 是一种通信规则或标准&#xff0c;用于定义通信双方或多方之间如何交互和传输数据。在计算机网络和通信系统中&#xff0c;协议规定了通信实体之间信息交换的格式、顺序、定时以及有关同步等事宜的约定。简易来说协议就是通信…

网络工程师---第三十八天

ISIS&#xff1a; ISIS含义&#xff1a;中间系统到中间系统IS-IS。 ISIS特点&#xff1a;①内部网关协议IGP&#xff08;Interior Gateway Protocol&#xff09;&#xff0c;用于自治系统内部&#xff1b; ②IS-IS也是一种链路状态协议&#xff0c;使用最短路径优先SPF算法进…

电子阅览室在管理时需注意什么

关于如今的绝大多数人来说&#xff0c;想必都听说过“电子阅览室”这一概念。它首要运用在校园中&#xff0c;给学生们供给愈加丰厚的常识储藏。它也是一个独立的局域网&#xff0c;在校园网络中作为重要的一个组成部分而存在。但是&#xff0c;一个好的电子阅览室是需求满意运…

python文件IO基础知识

目录 1.open函数打开文件 2.文件对象读写数据和关闭 3.文本文件和二进制文件的区别 4.编码和解码 读写文本文件时 读写二进制文件时 5.文件指针位置 6.文件缓存区与flush()方法 1.open函数打开文件 使用 open 函数创建一个文件对象&#xff0c;read 方法来读取数据&…

Docker学习(4):部署web项目

一、部署vue项目 在home目录下创建项目目录 将打包好的vue项目放入该目录下&#xff0c;dist是打包好的vue项目 在项目目录下&#xff0c;编辑default.conf 内容如下&#xff1a; server {listen 80;server_name localhost; # 修改为docker服务宿主机的iplocation / {r…

[JAVASE] 类和对象(六) -- 接口(续篇)

目录 一. Comparable接口 与 compareTo方法 1.1 Comparable接口 1.2 compareTo方法的重写 1.2.1 根据年龄进行比较 1.2.2 根据姓名进行比较 1.4 compareTo 方法 的使用 1.3 compareTo方法的缺点(重点) 二. Comparator接口 与 compare方法 2.1 Comparator接口 2.2 compare 方法…

使用AWR对电路进行交流仿真---以整流器仿真为例

使用AWR对电路进行交流仿真—以整流器仿真为例 生活不易&#xff0c;喵喵叹气。马上就要上班了&#xff0c;公司的ADS的版权紧缺&#xff0c;主要用的软件都是NI 的AWR&#xff0c;只能趁着现在没事做先学习一下子了&#xff0c;希望不要裁我。 本AWR专栏只是学习的小小记录而…

2024.5.25期末测试总结

成绩&#xff1a; 配置&#xff1a; 可能与实际有些出入 题目&#xff1a; 第一题&#xff1a; 代码思路&#xff1a; 一道模拟题&#xff0c;按照公式计算出sumpow(2,i)&#xff0c;判断sum>H&#xff0c;输出 代码&#xff1a; #include<bits/stdc.h> using name…

LiveGBS流媒体平台GB/T28181用户手册-基础配置:信令服务配置、流媒体服务配置、白名单、黑名单、更多配置

LiveGBS流媒体平台GB/T28181用户手册-基础配置:信令服务配置、流媒体服务配置、白名单、黑名单、更多配置 1、基础配置1.1、信令服务配置1.2、白名单1.3、黑名单1.4、流媒体服务配置 2、搭建GB28181视频直播平台 1、基础配置 LiveGBS相关信令服务配置和流媒体服务配置都在这里…

Spark运行模式详解

Spark概述 Spark 可以在多种不同的运行模式下执行&#xff0c;每种模式都有其自身的特点和适用场景。 部署Spark集群大体上分为两种模式&#xff1a;单机模式与集群模式。大多数分布式框架都支持单机模式&#xff0c;方便开发者调试框架的运行环境。但是在生产环境中&#xff…

机器人支持回调接口配置(详细教程)

大家伙&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 一、前言 今天&#xff0c;给大家介绍一下&#xff0c;如何在机器人中配置回调地址和接口编写。很多时候我们可能有这样的场景&#xff0c;收到消息后&#xff0c;想自己处理一下消息的内…

【微服务】springboot 构建镜像多种模式使用详解

目录 一、前言 二、微服务常用的镜像构建方案 3.1 使用Dockerfile 3.2 使用docker plugin插件 3.3 使用docker compose 编排文件 三、环境准备 3.1 服务器 3.2 安装JDK环境 3.2.1 创建目录 3.2.2 下载安装包 3.2.3 配置环境变量 2.2.4 查看java版本 3.3 安装maven …

MySQL中, 自增主键和UUID作为主键有什么区别?

首先我们来看看, 存储自增主键和uuid的数据类型 我们知道, mysql中作为主键的通常是int类型的数据, 这个 数据从第一条记录开始, 从1开始主键往后递增, 例如我有100条数据, 那么根据主键排序后, 里面的记录从上往下一次就是1, 2, 3 ... 100, 但是UUID就不一样了, UUID是根据特殊…

HTTP协议、URL、HTTPS协议 ----- 讲解很详细

本章重点 理解应用层的作用, 初识HTTP协议 了解HTTPS协议 一、HTTP协议 1.认识url 虽然我们说&#xff0c;应用层协议是我们程序猿自己定的&#xff0c;但实际上&#xff0c;已经有大佬们定义了一些现成的&#xff0c;又非常好用的应用层协议&#xff0c;供我们直接参考使…

明星IP切片带货爆单营,0基础搞定IP切片带货短视频(69节课)

把握带货趋势&#xff0c;了解切片流程&#xff0c;剪辑带货创收营 课程目录&#xff1a; 01第一章实操链路-第一节IP选择.mp4 02第一章实操链路-第二节账号准备.mp4 03第一章实操链路-第四节开通权限.mp4 04第一章实操链路-第五节货品准备.mp4 05第一章实操链路-第六节素…

AI重塑保险业未来:机器学习在风险评估、欺诈检测与客户服务中的深度应用

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

3d数字化虚拟交互展厅让您紧跟时代的步伐

虚实融合打破边界&#xff0c;北京VR虚拟数字展厅搭建让体验者彷如置身于一部三维电影中&#xff0c;可以对场景中的物体、角色、模型进行自由参观和体验&#xff0c;并且系统支持随时更新&#xff0c;让您紧跟时代的步伐&#xff0c;领略更新的展览风采。 除了常见的科普培训&…

OpenStack平台Nova管理

1. 规划节点 使用OpenStack平台节点规划 IP主机名节点192.168.100.10controller控制节点192.168.100.20compute计算节点 2. 基础准备 部署的OpenStack平台 1. Nova运维命令 &#xff08;1&#xff09;Nova管理安全组规划 安全组&#xff08;security group&#xff09;是…

Neural Networks and Deep Learning环境搭建

1.进入Anaconda prompt 2.创建虚拟环境 &#xff08;1&#xff09;最简单的创建 python 虚拟环境的命令是&#xff1a; conda create -n your_env_name # your_env_name 为你虚拟环境名&#xff08;2&#xff09;我在这里创建一个名为&#xff1a;deep_study的 python2.7版…

NextJs 初级篇 - 安装 | 路由 | 中间件

NextJs 初级篇 - 安装 | 路由 | 中间件 一. NextJs 的安装二. 路由2.1 路由和页面的定义2.2 布局的定义和使用2.3 模板的定义和使用① 模板 VS 布局② 什么是 use client 2.4 路由跳转的方式2.5 动态路由2.6 路由处理程序① GET 请求的默认缓存机制② 控制缓存或者退出缓存的手…