数据结构之单链表的详细实现(图解)

前言

本次博客讲结合图例讲解单向不带头非循环链表

此后会讲解一些题目

1单链表的实现

1.1什么是单链表

我们先看数组,即顺序表的是什么样的,再看链表

1.2单链表的特点

实际中要实现的链表的结构非常多样,以下情况组合起来就有8种链表结构:

1. 单向、双向

2. 带头、不带头

3. 循环、非循环

我们今天可以讲解最复杂的情况单向不带头非循环链表

1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结 构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。

2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都 是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带 来很多优势,实现反而简单了,后面我们代码实现了就知道了

链表的本质就是牺牲空间节省时间,它的访问速度快

1.2链表的实现

头文件部分
#pragma once
#define _SECURE_NO_WARNINGS 
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int datatype;
struct slnode{
	datatype data;
	struct slnode* next;
};
void slinit(struct slnode**pphead);
void slprint(struct slnode* phead);
void slPushBack(struct slnode** pphead,datatype put);
void slPushfront(struct slnode** pphead, datatype put);
void slPopfront(struct slnode** pphead);
void slPopback(struct slnode** pphead);
struct slnode* slFind(struct slnode* phead,datatype n);
void slInsertfront(struct slnode**pphead, datatype find,datatype i);
void slErase(struct slnode** pphead, datatype find);

大家简略看看就好,后面还会再提到,主要关注链表的定义

接下来讲解如何实现该链表

 初始化链表 slinit()

由于 没有哨兵位指针,所以它的初始化只需要让头指针为空即可

void slnodeinit(struct slnode **pphead)

{

*pphead=NULL;

}
扩展空间  struct slnode* buyslnode(datatype put)

如果要尾插或者头插一个链表,我们必须要动态开辟空间,才能增添一个结点

思路

首先他它有开辟一个空间,就必须要有一个指针记住该空间的地址

所以让该函数返回一个指针,注意在开辟成功后,必须要

让开辟的空间的next成员指向空指针,不然它就是一个野指针

struct slnode* buyslnode(datatype put)
{
	struct slnode* newnode = (struct slnode*)malloc(sizeof(struct slnode));
	if (newnode == NULL)
	{
		return NULL;
	}
	newnode->data = put;//插入元素的大小
	newnode->next = NULL;//赋值w为空指针
	return newnode;
}
 头插void slPushfront(struct slnode** pphead, datatype put)

思路

如果一开始没有一个结点,也就是 phead此时为NULL

要让  *phead=buyslnode(put);

否则就是普通的头插,此时画图让大家理解头插

但此时 不管头结点是不是NULL指针都可以直接通过以下代码实现头插

void slPushfront(struct slnode** pphead, datatype put)
{
	struct slnode* newnode = buyslnode(put);
		newnode->next = *pphead;
		*pphead = newnode;
}
尾插void slPushBack(struct slnode** pphead,datatype put)

思路

仍然考虑phead为NULL的情况,此时只要让newnode=*pphead即可

但是它是需要找到尾巴也就是最后一个非0结点

怎么找,看图

void slPushBack(struct slnode** pphead,datatype put)
{
	struct slnode* newnode = buyslnode(put);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		struct slnode* cur = *pphead;
		while (cur->next)
		{
			cur = cur->next;
		}
		cur->next = newnode;
	}
}
打印 void slprint(struct slnode* phead)

其实只需要遍历一遍即可

直接看代码

但是要注意这里是cur!=NULL才算遍历完

void slprint(struct slnode* phead)
{
	struct slnode* cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

到这里应该要测试一遍了

看图

这里分别尾插1 2 3 4 5 最后头插一个 0 再把他们打印出来

尾删 void slPopback(struct slnode** pphead)

分析

首先要有结点才能删除,所以头结点可以通过assert判断

如果只有一个结点让头指针置空

如果有两个以上的结点那么就找到尾巴并且找到尾巴前一个结点让它置空,并删除尾结点

看图吧

看代码

void slPopback(struct slnode** pphead)
{
	    assert(*pphead);
		struct slnode* cur = *pphead;
		struct slnode* prev = *pphead;
		if (cur->next == NULL)
		{
			free(*pphead);
			pphead = NULL;
		}
		else
		{
			while (cur->next)
			{
				prev = cur;
				cur = cur->next;
			}
			free(cur);
			prev->next = NULL;
		}

}

头删 void slPopfront(struct slnode** pphead)

分析

首先还是要有结点可删才可以删,所以还是要assert

其次还是这样,如果只有一个结点那就直接free掉

如果有两个以上的结点,还要找到下一个结点

看图

这里头删只要一个变量就可

void slPopfront(struct slnode** pphead)
{
	 assert(*pphead);
	 if ((*pphead)->next == NULL)
	 {
		free(*pphead);
		*pphead = NULL;
	 }
	else
	{
		struct slnode*tem = (*pphead)->next;
		free(*pphead);
		*pphead = tem;
	}
}
 定位 struct slnode* slFind(struct slnode* phead, datatype n)

分析

遍历一遍 判断即可

struct slnode* slFind(struct slnode* phead, datatype n)
{
	    assert(phead);
		while (phead)
		{
			if (phead->data== n)
			{
				return phead;
			}
			else
				phead = phead->next;
		}
		printf("没有该数据\n");
		return NULL;
}
 在pos前插入 void slInsertfront(struct slnode**pphead, datatype find, datatype i)

分析

先找到该位置,如果没有找到位置,结束

找到该位置后

如果该位置是第一个位置就是头插

还得找到这个位置的前一个位置把他们相连

看图

void slInsertfront(struct slnode**pphead, datatype find, datatype i)
{
	struct slnode* pfind=slFind(*pphead, find);
	if (pfind == NULL)
		return;
	else
	{
		if (pfind == *pphead)
			slPushfront(pphead, i);
		else
		{
			struct slnode* cur = *pphead;
			while (cur->next != pfind)
			{
				cur = cur->next;
			}
			cur->next = buyslnode(i);
			cur->next->next = pfind;
		}
	}
}
删除该位置的数据 void slErase(struct slnode** pphead, datatype find)

分析

但凡要删除数据就必须要有数据,所以还是要assert一下头指针

如果是pos位置在头指针位置即为头删 如果是在最后一个结点即为尾删

如果在中间,就是必须要找到前一个和后一个结点

看图

看代码

void slErase(struct slnode** pphead, datatype find)
{
	struct slnode* pfind = slFind(*pphead, find);
	if (pfind == *pphead)
	{
		*pphead = pfind->next;
		free(pfind);
	}
	else if(pfind->next==NULL)
	{
		slPopback(pphead);
	}
	else
	{
		struct slnode* cur = *pphead;
		while (cur->next != pfind)
		{
			cur = cur->next;
		}
		cur->next = pfind->next;
		free(pfind);
	}
}

至此基本所有的功能都实现了

我们可以测试一下

看看首先 尾插 1 2 3 4 5然后头插一个0

此时链表为 0 1 2 3 4 5 

然后再头删 尾删 链表为  1 2 3 4

再在2的位置前插入10,删除4这个结点

最终结果为 1 2 10 3      ok对上了

总结

到这里单链表的实现就完成了,还是多练

祝大家开心

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

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

相关文章

【业界动态】Digital Twin-数字孪生

绝大多数的人对数字孪生是一个模糊的概念&#xff0c;数字孪生也被称为数字映射、数字镜像&#xff0c;他既是一种技术&#xff0c;也是一种生态。随着互联网的建设与发展&#xff0c;数字孪生在未来又会如何发展&#xff0c;虚拟与现实之间会产生怎样的星火&#xff1f; 上帝按…

【MATLAB源码-第170期】基于matlab的BP神经网络股票价格预测GUI界面附带详细文档说明。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 基于BP神经网络的股票价格预测是一种利用人工神经网络中的反向传播&#xff08;Backpropagation&#xff0c;简称BP&#xff09;算法来预测股票市场价格变化的技术。这种方法通过模拟人脑的处理方式&#xff0c;尝试捕捉股票…

chrome 浏览器报错 This page will not function without javascript enabled

This page will not function without javascript enabled. Please enable javascript on your browser. 在访问公司spark history 页面时&#xff0c;发现页面加载不全&#xff0c;并提示如上报错&#xff0c;因此按照如下步骤&#xff0c;已解决问题。 在浏览器中启用 JavaS…

产品经理进阶:抖音电商的商业逻辑(抖店)

目录 内容简介 市场情况 作者简介 内容简介 最近看到很多人在讲如何开抖店、如何做无货源等等这些事情。 这个事本身没有什么问题&#xff0c;毕竟有人下场挖金子&#xff0c;就有人卖工具。 问题在于很多是边开店边传授知识&#xff0c;而抖店本身其实赚的是信息差的钱。…

Openstack创建和操作实例,实现与外部网络通信

一、熟悉OpenStack图形界面操作 1、了解Horizon项目 Horizon项目 各OpenStack服务的图形界面都是由Horizon提供的。Horizon提供基于Web的模块化用户界面。Horizon为云管理员提供一个整体的视图。Horizon为终端用户提供一个自主服务的门户。Horizon由云管理员进行管理与控制&a…

centos7.9安装mysql

1. 概述 官网&#xff1a;https://www.mysql.com/ MySQL是一个关系型数据库管理系统&#xff0c;由瑞典 MySQL AB 公司开发&#xff0c;MySQL是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的RDBMS (Relational Database Management S…

稀碎从零算法笔记Day28-LeetCode:零钱兑换

前言&#xff1a;鸽了好多天了哈哈哈&#xff0c;虽然C站没更但是LC还是坚持刷的&#xff0c;任重道远啊&#xff01;(可恶的寝室熄灯) 题型&#xff1a;动态规划 链接&#xff1a;322. 零钱兑换 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述…

张宏波:希望 MoonBit 可以成为世界级的编程语言以及配套的工具链

首场线下 MeetUp 精彩回顾来啦&#xff01; 3月23日&#xff0c;MoonBit 的首场线下 MeetUp 如期而至&#xff0c;带来了一场关于国产软件新发展的探讨。这场活动汇集了五位行业内的知名专家&#xff0c;他们围绕国产基础软件的新发展&#xff0c;分享了四个充满洞见的主题。从…

Springboot整合Redis报错:Unable to connection Redis

今天在做Springboot整合Redis中碰到下列错误&#xff1a; 基于以上的错误首先在Xshell或者其他远程操控虚拟机的软件上看能不能连接到Redis: [zzllocalhost ~]$ redis-cli -h 192.168.136.132 -p 6379 -a ****** Warning: Using a password with -a or -u option on the comma…

AI大模型学习——AI领域技术发展

目录 前言 一、AI大模型学习的理论基础 二、AI大模型的训练与优化 三、AI大模型在特定领域的应用 四、AI大模型学习的伦理与社会影响 五、未来发展趋势与挑战 总结 前言 在当前技术环境下&#xff0c;AI大模型学习不仅要求研究者具备深厚的数学基础和编程能力&#xff…

django orm DateTimeField 6位小数精度问题

from django.db.backends.mysql.base import DatabaseWrapperDatabaseWrapper.data_types[DateTimeField] "datetime"意思就是重写源码里面的DateTimeField字段

C++ 控制语句(一)

一 顺序结构 程序的基本结构有三种&#xff1a; 顺序结构、分支结构、循环结构 大量的实际问题需要通过各种控制流程来解决。 1.1 顺序结构 1.2 简单语句和复合语句 二 循环 2.1 for循环 语句流程图 注意&#xff1a;使用for语句的灵活性 三 while语句 四 do while语句

欧科云链OKLink:比特币第四次减半即将到来,收好这份数据宝典

减半一直是 Web3 领域重点关注的时间节点&#xff0c;由此产生的数据变动会对整个市场与生态产生关键影响。多链浏览器 OKLink 作为专业数据分析平台&#xff0c;一直以来在官方网站提供减半数据入口&#xff0c;供用户清晰查看各类资产的减半情况。&#x1f449; www.oklink.c…

Spring Boot 使用过滤器、拦截器、监听器

前言 作用 过滤器&#xff08;Filter&#xff09;&#xff1a;当有一堆请求&#xff0c;只希望符合预期的请求进来。拦截器&#xff08;Interceptor&#xff09;&#xff1a;想要干涉预期的请求。监听器&#xff08;Listener&#xff09;&#xff1a;想要监听这些请求具体做了…

Vue 与 React:前端框架对比分析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

docker网段冲突导致主机连接不上

前提&#xff1a;windows电脑链接liunx服务器&#xff0c;liunx服务器里面起了docker。 场景&#xff1a;在liunx服务器里面&#xff0c;用docker-compose up -d启动容器过程中&#xff0c;终止了windows服务器连接liunx服务器 可能原因&#xff1a;1.docker自身的网卡网段与连…

AMEYA360代理 | 江苏长晶科技FST2.0高性能 IGBT产品介绍

江苏长晶科技股份有限公司是一家专业从事半导体产品研发、生产和销售的企业。自2019年起&#xff0c;连续4年被中国半导体行业协会评为 “功率器件十强企业”。2021年开始自主研发有着“工业CPU”之称的IGBT&#xff0c;截至2023年Q3在家电/工业/新能源等行业实现8款产品市场应…

HCIP-Datacom(H12-821)题库补充(3/27)

最新 HCIP-Datacom&#xff08;H12-821&#xff09;完整题库请扫描上方二维码访问&#xff0c;持续更新中。 运行OSPF协议的路由器&#xff0c;所有接口必须属于同一个区域。 A&#xff1a;正确 B&#xff1a;错误 答案&#xff1a;B 解析&#xff1a;OSPF的邻居关系是基于…

HarmonyOS NEXT应用开发之ArkWeb同层渲染

介绍 该方案展示了ArkWeb同层渲染&#xff1a;将系统原生组件直接渲染到前端H5页面上&#xff0c;原生组件不仅可以提供H5组件无法实现的一些功能&#xff0c;还能提升用户体验的流畅度 效果图预览 使用说明 进入页面即可看到同层渲染效果&#xff0c;Text&#xff0c;searc…

3-iperf3 使用什么工具可以检测网络带宽、延迟和数据包丢失率等网络性能参数呢?

(1)iperf3简介 1.iperf3简介 2.用途&#xff08;特点&#xff09; 3.下载iperf3地址 &#xff08;2&#xff09;实战 1.iperf3参数 &#xff08;1&#xff09;通用参数&#xff08;客户端和服务器端都是适用的&#xff09; &#xff08;2&#xff09;客户端参数 实验1&…