8 单链表---带表头节点

news2025/1/12 6:15:06

上节课所学的顺序表的缺点

请添加图片描述
顺序表的最大问题:插入和删除时需要移动大量元素

链式存储的定义

请添加图片描述

链式存储的逻辑结构

请添加图片描述

链表中的基本概念:

请添加图片描述
注意:表头节点并不属于数据元素

单链表图示:

请添加图片描述

把3个需要的结构体定义出来:

请添加图片描述

typdef struct _tag_LinkList{
	LinkListNode header; //指针域
	int length; //单链表的长度
}TLinkList

获取第pos个元素

请添加图片描述
请添加图片描述

插入元素到pos位置

请添加图片描述

请添加图片描述
请添加图片描述
注意:新的链表形成之前,旧的链表不能断

删除元素:

请添加图片描述

请添加图片描述
请添加图片描述
一定要注意:index是从0开始还是从1开始【程序员永恒问题】

代码实现—单链表—带表头节点—头插法

linklist.c

#include "LinkList.h"

typedef struct _tag_LinkList
{
	LinkListNode* header;//头指针
	int length;//单链表的长度
}TLinkList; //类型:即代表头结点,又代表整个单链表

LinkList* LinkList_Create() {
	TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));

	if (ret) {
		ret->length = 0;
		ret->header = NULL;
	}
}

void LinkList_Destory(LinkList* list) {
	free(list);
}

void LinkList_Clear(LinkList* list) {
	((TLinkList*)list)->length = 0;
}

int LinkList_Length(LinkList* list) {
	return ((TLinkList*)list)->length;
}

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) {
	TLinkList* tll = (TLinkList*)list;
	int i = 0;

	int ret = -1;
	ret = (tll != NULL) && (pos >= 0) && (node != NULL);

	if (ret) {
		LinkListNode* current = (LinkListNode*)tll;

		//移动current指针到pos位置
		for (i=0; (i<pos)&&(current->next!=NULL); i++)
		{
			current = current->next;
		}

		//关键
		node->next = current->next;
		current->next = node;

		tll->length++;
	}

	return ret;
}

LinkListNode* LinkList_Get(LinkList* list, int pos) {
	TLinkList* tll = (TLinkList*)list;
	LinkListNode* ret = NULL;

	int i = 0;

	if ((tll != NULL) && (pos >= 0) && pos < tll->length) {
		LinkListNode* current = (LinkListNode*)tll;

		for (i=0;i<pos;i++)
		{
			current = current->next;
		}

		ret = current->next;
	}

	return ret;
}

LinkListNode* LinkList_Delete(LinkList* list, int pos) {
	TLinkList* tll = (TLinkList*)list;

	LinkListNode* ret = NULL;
	int i = 0;

	if ((tll != NULL) && (pos >= 0) && pos < tll->length) {
		LinkListNode* current = (LinkListNode*)tll;
		for (i = 0; i < pos; i++)
		{
			current = current->next;
		}

		ret = current->next;
		current->next = ret->next;

		tll->length--;
	}

	return ret;
}


linklist.h

#pragma once
#pragma once
#include <stdio.h>

typedef void LinkList;
//定义包含指针next的结构体
typedef struct _tag_LinkListNode LinkListNode;
typedef struct _tag_LinkListNode
{
	LinkListNode*  next;
};


/*
该方法用于创建并且返回一个空的线性表
*/
LinkList* LinkList_Create();

/*
该方法用于销毁一个线性表LinkList
*/
void LinkList_Destory(LinkList* list);

/*
该方法用于将一个线性表LinkList中的所有元素清空
使得线性表回到创建时的初始状态
*/
void LinkList_Clear(LinkList* list);

/*
该方法用于返回一个线性表LinkList中的所有元素个数
*/
int LinkList_Length(LinkList* list);

int LinkList_Capacity(LinkList* list);

/*
该方法用于向一个线性表LinkList的pos位置处插入新元素node
返回值为1表示插入成功,0表示插入失败
*/
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);

/*
该方法用于获取一个线性表LinkList的pos位置处的元素
返回值为pos位置处的元素,NULL表示获取失败
*/
LinkListNode* LinkList_Get(LinkList* list, int pos);

/*
该方法用于删除一个线性表LinkList的pos位置处的元素
返回值为被删除的元素,NULL表示删除失败
*/
LinkListNode* LinkList_Delete(LinkList* list, int pos);


main.c


#include "LinkList.h"

//普通节点的结构体
struct Value
{
	LinkListNode* header; //指针域
	int v;//数据域
};
int main() {
	int i = 0;
	LinkList* list = LinkList_Create();

	struct Value v1;
	struct Value v2;
	struct Value v3;
	struct Value v4;
	struct Value v5;

	v1.v = 1;
	v2.v = 2;
	v3.v = 3;
	v4.v = 4;
	v5.v = 5;

	//头插法
	LinkList_Insert(list, (LinkListNode*)&v1, 0);
	LinkList_Insert(list, (LinkListNode*)&v2, 0);
	LinkList_Insert(list, (LinkListNode*)&v3, 0);
	LinkList_Insert(list, (LinkListNode*)&v4, 0);
	LinkList_Insert(list, (LinkListNode*)&v5, 0);

	for (i = 0; i < LinkList_Length(list); i++)
	{
	  	struct Value* pv = LinkList_Get(list, i);
		printf("%d\n", pv->v);
	}

	while (LinkList_Length(list) >0)
	{
		struct Value* pv = LinkList_Delete(list, LinkList_Length(list) - 1);
		printf("%d\n", pv->v);
	}

	LinkList_Destory(list);

	return 0;
}

运行结果:
请添加图片描述

尾插法

请添加图片描述

小结:单链表的优点和缺点

请添加图片描述

末尾问题:

请添加图片描述
这也是我想问的!

请添加图片描述
单链表:在选择表头结点和无表头结点的实现方式时,应根据具体的应用场景和需求来考虑。一般而言,表头结点方式更为常见和直观,更容易管理和操作链表但无表头结点的实现方式可能更加节省一些空间

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

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

相关文章

《网络是怎样连接的》2.3节图表(自用)

图4.1&#xff1a;TCP拆分数据与ACK号 图4.2&#xff1a;实际工作中ACK号与序号的交互过程 首先&#xff0c;客户端在连接时需要计算出与从客户端到服务器方向通信相关的序号初始值&#xff0c;并将这个值发送给服务器&#xff08;①&#xff09;。 接下来&#xff0c;服务器会…

MySQL学习笔记2: MySQL的前置知识

目录 1. MySQL是什么?2. 什么是客户端&#xff0c;什么是服务器&#xff1f;3. 服务器的特点4. 安装mysql5. mysql 客户端6. mysql 服务器7. mysql的本体8. MySQL 使用什么来存储数据&#xff1f;9. 数据库的多种含义10. MySQL 存储数据的组织方式 1. MySQL是什么? MySQL 是…

新手养布偶猫如何选择猫主食冻干?K9、sc、希喂三个品牌推荐!

布偶猫是食肉动物&#xff0c;但由于肠胃脆弱敏感&#xff0c;所以在饮食上需要特别关注哦&#xff01;为了给它们最好的呵护&#xff0c;现在有了主食冻干这种优质猫主食&#xff01;它不仅符合猫咪的天然饮食习惯&#xff0c;还用了新鲜生肉做原料呢&#xff01;营养满分不说…

如何设计企业级业务流程?学习华为的流程六级分类经验

业务流程管理&#xff08;BPM&#xff09;是一种系统化的方法&#xff0c;用于分析、设计、执行、监控和优化组织的业务流程&#xff0c;以实现预期的目标和价值。业务流程管理中&#xff0c;流程的分级方法有多种&#xff0c;常见的有以下几种&#xff1a; APQC的流程分级方法…

Agilent安捷伦E4407B频谱分析仪26.5GHz

E4407B是安捷伦ESA-E系列频谱分析仪&#xff0c;它是一款能够适应未来需要的中性能频谱分析仪解决方案。该系列在测量速度、动态范围、精度和功率分辨能力上&#xff0c;都为类似价位的产品建立了性能标准。其灵活的平台设计使得研发、制造和现场服务工程师能够自定义产品&…

(Python + Selenium4)Web自动化测试自学Day2之动手尝试

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;小试牛刀关于select标签关于弹窗只有一个点击按钮的弹窗需要确认的弹窗用户可以输入的弹窗 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程语言基础&#xff0c;非编程小白&#xff09;的 Python Selenium4 Web自动化测试…

在 docker 容器中配置双网卡,解决通讯的问题

目录 1. 查看当前网络信息 2. 创建自定义网络桥 3. 创建双网卡模式 4. 删除默认网卡 已经创建好了的 Docker 容器&#xff0c;要修改它的IP比较麻烦&#xff0c;网上找了几种不同的方法&#xff0c;经过试验都没有成功&#xff0c;下面通过配置双网上来解决 IP 的问题。…

无心剑七绝《译无止境》

七绝译无止境 人生跌宕几春秋 苦辣酸甜永不休 只待通灵成妙译 神思曼舞醉琼楼 2024年1月6日 平水韵十一尤平韵 无心剑的这首《译无止境》以七言绝句的形式&#xff0c;表达了对翻译事业的热爱和追求。 首句“人生跌宕几春秋”&#xff0c;意味着人生的曲折变化&#xff0c…

IP代理测试:Ping测试如何做?

您在访问互联网时是否遇到过持续滞后或花费很长时间等待网站加载的情况&#xff1f;为了避免这种情况&#xff0c;您可以测试 ping 以查看连接速度。如果您使用代理&#xff0c;此 ping 测试还会显示代理服务器的响应速度。 ping 测试是一个很有价值的工具&#xff0c;可以帮助…

修改mariadb的默认存储路径

首先mariadb服务正常启动 安装mariadb&#xff1a; https://blog.csdn.net/qq_50247813/article/details/135402502?spm1001.2014.3001.5502 停止mariadb服务 systemctl stop mariadb创建新的数据存放目录 mkdir /data将mariadb的数据拷贝到/data目录下 mv /var/lib/mysq…

Python+Appium自动化测试的使用步骤

这篇文章主要介绍了PythonAppium实现自动化测试的使用步骤&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 一、环境准备 1.脚本语言&#xff1a;Python3.x IDE&…

GLTF编辑器设置3D纺织纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 位移贴图是一种纹理映射技术&#xff0c;通过改变顶点的位置来模拟细…

I.MX6ULL开发笔记(三)——挂载NFS网络文件系统

0x01 网络文件系统 当我们在编译一个文件时&#xff0c;正常是在一个pc上编译好一个文件&#xff0c;之后丢到开发板上去运行。如果有了NFS网络文件系统&#xff0c;那么我们就可以在PC以及开发板上共享文件了。 网络文件系统&#xff0c;常被称为NFS&#xff08;Network Fil…

计算机基础知识——校验码概述

目录 1 码距 2 奇偶校验 3 CRC循环冗余校验码 3.1 多项式 3.2 编码的组成 3.3 生成多项式 3.4 校验码的生成 4 海明校验码和恒比码 4.1 校验方程 4.2 恒比码 1 码距 码距是恒量一种编码方式的抗错误能力的一个指标。数字信息在传输和存取的过程中&#xff0c;由于…

k8s的陈述式管理

k8s的陈述式管理&#xff1a; 所谓的陈述式管离也就是命令行工具 优点&#xff1a;90%以上都可以满足 对资源的增删查比较方便&#xff0c;对改不是很友好 缺点&#xff1a;命令比较冗长&#xff0c;复杂&#xff0c;难记 声明式&#xff1a; k8s当中的YAML文件来实现资源管…

MySQL之视图案例

目录 一.视图1.1 含义1.2 操作 二.案例三.思维导图 一.视图 1.1 含义 虚拟表&#xff0c;和普通表一样使用 1.2 操作 1.创建视图 create view 视图名 as 查询语句&#xff1b; 2.视图的修改 方式一&#xff1a; create or replace view 视图名 as 查询语句 方式二&#x…

初始py和py开发工具

前言&#xff1a;上一章节给友友们讲解了如何安装py环境&#xff0c;这一章节就来练习一下如何写py的程序以及注意事项。 目录 一.你好世界 1.因为主播liunx用习惯的缘故所以所有的操作都在liunx上面执行&#xff0c;下面我们来看怎么写py的程序&#xff0c; 1.1首先打开liu…

欧系数学一眼假系列7.“欧拉常数”是弥天大谎

数学界一直在干一件令人恶心的丑事&#xff1a;明明我求的是Σ1/708249541360742487&#xff0c;它给的答案却是ln7082495413607424870.5772156649(欧拉常数&#xff0c;通常以C表示)&#xff0c;门外汉皆以为Σ1/n→∞是正经结论&#xff0c;全然不知它无关Σ1/n&#xff0c;而…

Java集合教程

文章目录 1、集合体系结构2、单列集合2.1 Collection2.1.1 Collection集合概述和使用2.1.2 自定义对象比较2.1.3 Collection集合的遍历2.1.3.1 迭代器遍历2.1.3.2 增强for2.1.3.3 lambda表达式 2.2 List2.2.1 List集合的概述和特点2.2.2 List集合的特有方法2.2.3 List集合的两个…

[足式机器人]Part2 Dr. CAN学习笔记-动态系统建模与分析 Ch02-1+2课程介绍+电路系统建模、基尔霍夫定律

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-动态系统建模与分析 Ch02-12课程介绍电路系统建模、基尔霍夫定律 1. 课程介绍2. 电路系统建模、基尔霍夫定律 1. 课程介绍 2. 电路系统建模、基尔霍夫定律 基本元件&#xff1a; 电量 库伦&…