用指针处理链表(一)

1链表概述

        链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。我们知道,用数组存放数据时,必须事先定义固定的长度(即元素个数)。比如,有的班级有100人,而有的班只有30人,如果要用同一个数组先后存放不同班级的学生数据,则必须定义长度为100的数组。如果事先难以确定一个班的最多人数,则必须把数组定得足够大,以能存放任何班级的学生数据。显然这将会浪费内存。链表则没有这种缺点,它根据需要开辟内存单元。图11.10表示最简单的一种链表(单向链表)的结构。

        链表有一个“头指针”变量,图中以head 表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。可以看出,head指向第一个元素;第一个元素又指向第二个元素……直到最后一个元素,该元素不再指向其他元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。

        可以看到链表中各元素在内存中可以不是连续存放的。要找某一元素,必须先找到上一个元素,根据它提供的下一元素地址才能找到下一个元素。如果不提供“头指针”(head),则整个链表都无法访问。链表如同一条铁链一样,一环扣一环,中间是不能断开的。打个通俗的比方:幼儿园的老师带领孩子出来散步,老师牵着第一个小孩的手,第一个小孩的另一只手牵着第二个孩子……这就是一个“链”,最后一个孩子有一只手空着,他是“链尾”。要找这个队伍,必须先找到老师,然后顺序找到每一个孩子。

        可以看到,这种链表的数据结构,必须利用指针变量才能实现。即:一个结点中应包含一个指针变量,用它存放下一结点的地址。

        前面介绍了结构体变量,用它作链表中的结点是最合适的。一个结构体变量包含若干成员,这些成员可以是数值类型、字符类型、数组类型,也可以是指针类型。我们用这个指针类型成员来存放下一个结点的地址。例如,可以设计这样一个结构体类型:

struct student

{int num;

float score ;

struct student * next ;

};

其中成员 num 和score用来存放结点中的有用数据(用户需要用到的数据),相当于图 11.10 结点中的A,B,C,D。next是指针类型的成员,它指向struct student类型数据(这就是next所在的结构体类型)。一个指针类型的成员既可以指向其他类型的结构体数据,也可以指向自己所在的结构体类型的数据。现在,next是struct student类型中的一个成员,它又指向struct student类型的数据。用这种方法就可以建立链表。见图11.11

        图中每一个结点都属于struct student类型,它的成员next存放下一结点的地址,程序设计人员可以不必具体知道各结点的地址,只要保证将下一个结点的地址放到前一结点的成员next 中即可。

        请注意:上面只是定义了一个 structstudent 类型,并未实际分配存储空间。只有定义了变量才分配内存单元。

2 简单链表

下面通过一个例子来说明如何建立和输出一个简单链表。

例11.7 建立一个如图11.11所示的简单链表,它由3个学生数据的结点组成。输出各结点中的数据。

# define NULL 0

struct student

{long num;

Hloat score;

struct student*next;

}:

main()

{struct student a,b,c,* head,*p;

a.num=99101; a.score=89.5;

b. num=99103;b.score=90;

c.num=99107; c.score=85;                 /*对结点的num 和 score成员赋值*/

head=&a;                                            /*将结点a的起始地址赋给头指针head*/

a. next =&b;                                         /*将结点b的起始地址赋给a结点的next 成员*/

b.next=&c;                                           /*将结点c的起始地址赋给b结点的next成员*/

e. next=NULL;                                      /*c结点的 next成员不存放其他结点地址*/

p=head;                                                 /*使p指针指向a结点*/

do

{printf(" %ld %5.1f\n" ,p→>num,p->score);

/*输出p指向的结点的数据*/

p=p->next; /*使p指向下一结点*/

}while(p! =NULL); /*输出完c结点后p的值为NULL*/

}

请读者仔细考虑:①各个结点是怎样构成链表的。②没有头指针head行不行?③p起什么作用?没有它行不行?

开始时使head 指向a结点,a.next 指向b结点,b.next 指向c结点,这就构成链表关系。“c.next=NULL”的作用是使c.next不指向任何有用的存储单元。在输出链表时要借助p,先使p指向a结点,然后输出a结点中的数据,“p=p->next”是为输出下一个结点做准备。p一>next的值是b结点的地址,因此执行“p=p->next”后p就指向b结点,所以在下一次循环时输出的是b结点中的数据。

本例是比较简单的,所有结点都是在程序中定义的,不是临时开辟的,也不能用完后

释放,这种链表称为“静态链表”。

3 处理动态链表所需的函数

前面讲过,链表结构是动态地分配存储的,即在需要时才开辟一个结点的存储单元。怎样动态地开辟和释放存储单元呢?C语言编译系统的库函数提供了以下有关函数。

1. malloc 函数其函数原型为

void* malloc (unsigned int size);

其作用是在内存的动态存储区中分配一个长度为size的连续空间。此函数的值(即“返回值”)是一个指向分配域起始地址的指针(类型为void)。如果此函数未能成功地执行(例如 存空间不足),则返回空指针(NULL)。

2. calloc 函数其函数原型为

void* calloc (unsigned n ,unsigned size);

其作用是在内存的动态区存储中分配n个长度为size的连续空间。函数返回一个指向分配域起始地址的指针;如果分配不成功,返回NULL。

用calloc 函数可以为一维数组开辟动态存储空间,n为数组元素个数,每个元素长度为size。

3. free 函数其函数原型为

void free(void *p);

其作用是释放由p指向的内存区,使这部分内存区能被其他变量使用。p是最近一次调用 calloc 或malloc函数时返回的值。free函数无返回值。

请注意:以前的C版本提供的malloc和calloc函数得到的是指向字符型数据的指针。ANSIC提供的malloc和calloc函数规定为void*类型。

有了本节所介绍的初步知识,下面就可以对链表进行操作了(包括建立链表、插入或删除链表中一个结点等)。有些概念需要在后面的应用中逐步建立和掌握。

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

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

相关文章

为wordpress特定分类目录下的内容添加自定义字段

在WordPress中,您可以使用自定义字段(Custom Fields)或称为元数据(Meta Data)来为特定分类目录下的内容添加额外的信息。自定义字段可以附加到文章、页面、用户和其他对象上。以下是一个逐步指南,介绍如何为特定分类目录下的内容添加自定义字段&#xff…

男青年穿什么裤子好看?适合男生穿的百搭神裤

这几年衣服的款式可谓是越来越多了,很多男生在选裤子的时候都发现虽然款式越来越多,但现在市面上的裤子质量参差不齐,导致难以选择。而且还有很多商家为了利润采用低廉的材料,从而上身舒适性极差。 那么今天就给大家详细介绍几点…

web3 token 如何理解

"Web3 Token"是指建立在Web3技术堆栈上的数字令牌。为了更好地理解这个概念,让我们逐步解释: Web3:指的是下一代互联网(Web3.0),它是基于区块链技术的去中心化网络。Web3的核心理念是去中心化、安…

cpu自动加速@TDP@睿频TurboBoost@PB精准频率提升技术

文章目录 自动加速技术Intel超频睿频工作原理:特点超频技术对比 AMDPBO PB2 TDP定义与意义TDP与实际功耗TDP的应用TDP的发展与挑战 Intel相关指标PL1 (Power Limit 1)PL2 (Power Limit 2)PL1 与 PL2 的关系与应用场景小结查看 AMD相关指标主板厂商与用户干预 高端型号的加速技术…

3D软件坐标系速查

本文介绍不同3D软件的世界坐标系之间的差异及其工作原理。 基本上,游戏引擎和3D软件包最重要的问题是根据软件的坐标轴系统创建资产,正确缩放它们并根据要完成的工作设置枢轴系统。 坐标系正确性的定义可能会根据模型导入的游戏引擎或 3D 软件而变化。…

开放式耳机性价比高的品牌有哪些呢?五大高性价比选购清单

不入耳开放式蓝牙耳机近两年开始火起来了,因为它佩戴的舒适性和安全性两方面受到了很多人的关注。开放式的设计,就算不放进耳朵里也能听歌,同时加上它独特的空气传导的传声途径,整体的音质还是很不错的。不压耳,不涨耳…

申请发明专利的基本条件是什么?发明专利需要什么资料?

发明专利申请的基本条件是什么?发明专利需要的资料有啥?发明专利大家真的了,那么今天的这2个问题我们就一起来看看吧。 发明专利申请的基本条件是什么? 在进行技术开发、新产品研制过程中取得的成果,因其技术水平较高&#xff0…

2016年认证杯SPSSPRO杯数学建模D题(第二阶段)NBA是否有必要设立四分线全过程文档及程序

2016年认证杯SPSSPRO杯数学建模 D题 NBA是否有必要设立四分线 原题再现: NBA 联盟从 1946 年成立到今天,一路上经历过无数次规则上的变迁。有顺应民意、皆大欢喜的,比如 1973 年在技术统计中增加了抢断和盖帽数据;有应运而生、力…

Filter PWM和普通PWM区别

Filter PWM和普通PWM是两种不同的脉冲宽度调制(PWM)技术。它们的区别主要在于滤波器的使用和输出信号的特性。 普通PWM是一种基本的PWM技术,它通过改变信号的脉冲宽度来控制输出电平的平均值。普通PWM信号的频率通常较高,可以达到…

通过MobaXterm工具远程连接可视化服务器桌面并操控

目录 一、MobaXterm工具二、MobaXterm工具可视化服务器目录三、MobaXterm工具可视化服务器桌面 一、MobaXterm工具 MobaXterm是一款功能强大的远程连接工具,可以用于连接到各种类型的服务器,包括Linux、Windows和MacOS。它支持多种协议,包括…

【C语言】linux内核pci_enable_device函数和_PCI_NOP宏

pci_enable_device 一、注释 static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) {struct pci_dev *bridge;int err;int i, bars 0;/** 此时电源状态可能是未知的,可能是由于新启动或者设备移除调用。* 因此获取当前的电源状态&…

【Java】哈希表

文章目录 一、概念二、哈希冲突2.1概念2.2设计合理的哈希函数-避免冲突2.3调节负载因子-避免冲突2.4闭散列-冲突解决(了解)2.5开散列/哈希桶-冲突解决(重点掌握) 三、代码实现3.1成员变量及方法的设定3.2插入3.3重新哈希3.4 获取到…

YT8531调试记录

总结 还是从设备树,mac驱动,mac驱动对mdio总线的注册,phy驱动 ,phy的datasheet,cpu的datasheet 几个方面来看来看 0.确认供电,以及phy的地址(一般会有多个地址,根据相关引脚电平可配置) 1.确…

第二十九天-Flask框架web开发

目录 1.介绍 2.安装 虚拟环境安装 3.使用 1.第一个Flask程序 2.MTV模式 3.启动选项以及调试 启动 调试模式 Pycharm启动配置 4.Flask的扩展 5.url配置和路由 6.响应上下文对象 ​编辑7.请求保报文常用参数 8.响应报文 9.重定向等内部视图 1.介绍 网址&#xff1…

BEVFormer v2论文阅读

摘要 本文工作 提出了一种具有透视监督(perspective supervision)的新型鸟瞰(BEV)检测器,该检测器收敛速度更快,更适合现代图像骨干。现有的最先进的BEV检测器通常与VovNet等特定深度预训练的主干相连,阻碍了蓬勃发展…

Diffuison在域自适应中 笔记

1 Title Diffusion-based Target Sampler for Unsupervised Domain Adaptation(Zhang, Yulong, Chen, Shuhao, Zhang, Yu, Lu, Jiang)【CVPR 2023】 2 Conclusion large domain shifts and the sample scarcity in the target domain make exis…

LeetCode:2642. 设计可以求最短路径的图类(SPFA Java)

目录 2642. 设计可以求最短路径的图类 题目描述: 实现代码与解析: SPFA 原理思路: 2642. 设计可以求最短路径的图类 题目描述: 给你一个有 n 个节点的 有向带权 图,节点编号为 0 到 n - 1 。图中的初始边用数组 e…

【开发篇】六、查询大量数据导致内存溢出

文章目录 1、溢出场景2、快照文件分析3、本地环境复现4、结论5、解决思路 记录一个问题,工作中有个数据处理服务OOM,查了下镜像的dockerfile,发现JVM参数如下。很明显,一个数据服务,里面经手大量的数据对象&#xff0c…

浏览器地址栏输入地址发生什么(浏览器输入不同的地址类型会导致不同的以为和结果)

浏览器输入不同的地址类型会导致不同的以为和结果。 大多数情况下 当在浏览器的地址栏输入一个地址时,通常情况下浏览器会发起一个HTTP请求来获取该地址对应的网页内容。 当在浏览器的地址栏输入一个地址时,浏览器会进行DNS域名解析,得到IP…

【概率基础】从概率角度去解释回归和分类的主要区别是什么?

1. 从概率角度去解释回归和分类的主要区别是什么? 从概率角度来看,回归和分类任务的主要区别在于它们各自预测的目标变量的性质,以及如何使用概率来对这些预测进行建模。 回归 回归任务旨在预测一个连续值的目标变量。在概率术语中,回归模…