S1E45:单链表1 课后作业

测试题:
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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue.Draggable:强大的Vue拖放组件技术探索

一、引言 随着前端技术的不断发展&#xff0c;拖放&#xff08;Drag-and-Drop&#xff09;功能已经成为许多Web应用不可或缺的一部分。Vue.js作为现代前端框架的佼佼者&#xff0c;为开发者提供了丰富的生态系统和强大的工具链。Vue.Draggable作为基于Sortable.js的Vue拖放组件…

在二十三届中国科学家论坛大会上,郎百忠被授予《中国首席政治书法领域科学家》荣誉称号

在5月25日于北京举办的第二十三届中国科学家论坛上&#xff0c;备受瞩目的书法家郎百忠凭借其卓越的书法造诣和深厚的政治素养&#xff0c;荣获了"中国首席政治书法科学家"称号。这一荣誉是对郎百忠多年来在书法领域的杰出贡献以及他在政治书法领域的卓越成就的肯定。…

leedcode【19】. 删除链表的倒数第 N 个结点——Java解法

Problem: 19. 删除链表的倒数第 N 个结点 思路解题方法复杂度Code性能 思路 如果要删除倒数第n个节点&#xff0c;让fast移动n步&#xff0c;然后让fast和slow同时移动&#xff0c;直到fast指向链表末尾。删掉slow所指向的节点就可以了。 分为如下几步&#xff1a; 定义fast指…

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

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

Adobe Bridge BR v14.0.3 安装教程 (多媒体文件组织管理工具)

Adobe系列软件安装目录 一、Adobe Photoshop PS 25.6.0 安装教程 (最流行的图像设计软件) 二、Adobe Media Encoder ME v24.3.0 安装教程 (视频和音频编码渲染工具) 三、Adobe Premiere Pro v24.3.0 安装教程 (领先的视频编辑软件) 四、Adobe After Effects AE v24.3.0 安装…

C/C++ vector详解

要想了解STL&#xff0c;就必须会看&#xff1a; cplusplus.comhttps://legacy.cplusplus.com/ 官方内容全都是英文的&#xff0c;可以参考&#xff1a; C/C初始识https://blog.csdn.net/2301_77087344/article/details/138596294?spm1001.2014.3001.5501 vector&#xff…

【LakeHouse】Apache Iceberg + Amoro 助力网易构建云原生湖仓

Apache Iceberg Amoro 助力网易构建云原生湖仓 1.云原生湖仓背景与挑战2.Apache Iceberg 、Amoro 与云原生2.1 Apache Iceberg2.2 Amoro 简介 3.Apache Iceberg Amoro 云原生实践3.1 云上湖仓案例一3.2 云上湖仓案例二3.3 云上湖仓案例三 4.Amoro 未来发展规划 出品社区&…

Dubbo生态之nacos

1.Nacos简介 在博客Dubbo生态之初识dubbo协议-CSDN博客种我们已经介绍了为什么要使用注册中心&#xff0c;nacos作为注册中心的一种&#xff0c;相对于其它的主流注册中心有什么区别呢? NacosEurekaZookeeper数据存储存储在内存存储在内存存储在内存通信协议gRPChttpjute协议…

Yolov9调用COCOAPI生成APs,APm,APl

最近在做小目标检测的东西&#xff0c;因为后期毕业论文需要&#xff0c;所以开始使用Yolov9模型&#xff0c;运行val.py的时候不会自己产生小目标的AP指标&#xff0c;所以研究了一下&#xff0c;步骤非常简单&#xff1a; 第一步&#xff1a; 在数据集中生成json格式的Annota…

ISCC2024个人挑战赛WP-DLLCode

&#xff08;非官方解&#xff0c;以下内容均互联网收集的信息和个人思路&#xff0c;仅供学习参考&#xff09; 注意到程序调用了Encode函数对明文进行加密&#xff0c;点进去发现是对外部DLL的调用 静态分析DLL中的Encode函数可以得到 写出对应的解密脚本如下 #include <…

【三维修复、分割与编辑】InFusion、Bootstrap 3D、GaussianGrouping、GaussianEditor等(论文总结)

提示&#xff1a; 文章目录 前言一、InFusion&#xff1a;扩散模型助力&#xff0c;效率提高20倍&#xff01;(2024)1. 摘要2. 算法3. 效果 二、2D Gaussian Splatting三、Bootstrap 3D:从扩散模型引导三维重建1.摘要2.相关工作3.方法1.Boostrapping by Diffusion 通过扩散模型…

搭建访问阿里云百炼大模型环境

最近这波大降价&#xff0c;还有限时免费&#xff0c;还不赶快试试在线大模型&#xff1f;下面整理访问百炼平台的千问模型方法。 创建RAM子账号并授权 创建RAM子账号 1. “访问控制RAM”入口&#xff08;控制台URL&#xff09; 然后点击进入“RAM管理控制台” 2. 添加用户 …

漫谈企业信息化安全-综述

一、前言 一直以来想写一些文章&#xff0c;谈一谈企业信息化过程中的安全问题及对策。 随着信息技术的不断发展和普及&#xff0c;特别是今年来移动办公、云服务等等新的工作模式和新的信息技术的应用&#xff0c;企业信息化已经成为提升竞争力、促进创新和发展的重要途径。…

Spark-RDD-依赖关系详解

Spark概述 Spark-RDD概述 Spark-RDD-依赖关系 在Apache Spark中&#xff0c;RDD&#xff08;Resilient Distributed Dataset&#xff09;是一种基本的抽象数据结构&#xff0c;代表了分布式的、不可变的数据集。 RDD之间的依赖关系在Spark中非常重要&#xff0c;因为它们决定了…

MySQL 存储过程(实验报告)

一、实验名称&#xff1a; 存储过程 二、实验日期&#xff1a; 2024 年5 月 25 日 三、实验目的&#xff1a; 掌握MySQL存储过程的创建及调用&#xff1b; 四、实验用的仪器和材料&#xff1a; 硬件&#xff1a;PC电脑一台&#xff1b; 配置&#xff1a;内存&#xff0…

mysql事务 事务并发问题 隔离级别 以及原理

mysql事务 简介&#xff1a;事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务四大特性 原子性&#xff08;Atomici…

多模态交互式 AI 代理的兴起:探索 Google 的 Astra 和 OpenAI 的 ChatGPT-4o应用

OpenAI的发展 聊天GPT-4o 和 谷歌的阿斯特拉 标志着交互式人工智能代理的新阶段&#xff1a;多模式交互式人工智能代理的兴起。这次旅程开始于 Siri 和 Alexa的&#xff0c;它将语音激活的人工智能带入主流用途&#xff0c;并通过语音命令改变了我们与技术的交互。尽管有影响&a…

链表类型的无界阻塞线程安全队列-ConcurrentLinkedQueue(FIFO)

ConcurrentLinkedQueue是非阻塞线程安全(volatile不能完全保证线程安全)的队列,适用于“高并发”的场景。是一个基于链表节点的无界线程安全队列,按照 FIFO(先进先出,尾先进头先出)原则对元素进行排序。队列元素中不可以放置null元素(内部实现的特殊节点除外)。 volati…

linux笔记6--shell相关

文章目录 1. 查看当前的shell类型2. ps -f命令3. 父子shell4. 分号在命令里的作用问题&#xff1a;环境变量echo&#xff1a; 5. sleep和jobssleep:jobs:例子&#xff1a;&: 6. 外部命令和内建命令图解外部命令type命令 7. history命令8. alias命令9. 推荐 1. 查看当前的sh…

2024年推荐的适合电脑和手机操作的线上兼职副业平台

总是会有人在找寻着线上兼职副业&#xff0c;那么在如今的2024年&#xff0c;互联网提供了诸多方便&#xff0c;无论你是宝妈、大学生、程序员、外卖小哥还是打工族&#xff0c;如果你正在寻找副业机会&#xff0c;那么这篇文章将为你提供一些适合电脑和手机操作的线上兼职副业…