当前位置: 首页 > news >正文

手写单链表(指针)(next域)附图

目录

创建文件:

具体实现:

首先是头插。

注意:一定要注意:再定义tmp时,要给它赋一个初始值(推荐使用 new list_next)

接着是尾插:

随后是中间插:

然后是最简单的改值:

随后是删头:

 一定要注意(size--) 

删中间:

末尾:

oh,对了:


我们知道单链表,今天博主(也就是我)自己手写了一个单链表(用指针写的)现在我来分享一下。

创建文件:

我用三个来写(list.h,listfun.h,run.cpp)(run.cpp)用来调试

具体实现:

list.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<limits.h>
struct list_next{//链表的一个值int value;struct list_next *next;
};
struct list_make{//一条链表的结构list_next *head;list_next *tail;int size;
};
//void head_add(list_next* &head,int v,int &size);//头插 
//void tail_add(list_next* &tail,int v,int &size);//尾插 
//void add_node(list_next* head,int p,int v,list_next* tail,int &size);//插入 
//void change(list_next* head,int p,int v);//改值 
//void head_del(list_next* &head,int &size);//头删 
//void del_node(list_next* head,int p,list_next* &tail,int &size);//删除
//void init(list_make &p,int v) //初始化 

接下来就是核心的listfun.h

首先是头插。

函数定义:

void head_add(list_next* &head,int v,int &size)

(这里用了引用,不会的童鞋们请看->引用教程 

先用图来演示:(左边是值,右边是next域)

​​​​​​​

上图是原来的样子,tmp是要插入的数。

list_next* tmp=new list_next;
tmp->value=v;

 接着把tmp的next改成head。

tmp->next=head;

再把头换成tmp。

head = tmp;

 最后,size+1(因为长度增加了)

size++;

所以头插代码就是:

void head_add(list_next* &head,int v,int &size)
{list_next* tmp=new list_next;tmp->value=v;tmp->next=head;head = tmp;size++;
}

注意:一定要注意:再定义tmp时,要给它赋一个初始值(推荐使用 new list_next)

接着是尾插:

函数定义:

void tail_add(list_next* &tail,int v,int &size)

还是回到那张图:

把tmp初始化:

​​list_next* tmp=new list_next;
tmp->value=v;
tmp->next=NULL;

把尾的next变成tmp。

tail -> next=tmp;

把tmp变成尾:

tail = tmp;

最后size++;

整理后代码:

void tail_add(list_next* &tail,int v,int &size)
{list_next* tmp=new list_next;tmp->value=v;tmp->next=NULL;tail -> next=tmp;tail = tmp;size++;
}

随后是中间插:

函数定义:

void add_node(list_next* head,int p,int v,list_next* &tail,int &size)

几句可以加快速度的代码:

if(p == 0)
{head_add(head,v,size);
} 
if(p == size)
{tail_add(tail,v,size);return ;
}

来正式的:

首先找到第p个:

list_next* tmp=new list_next;//初始化
tmp->value = v;
int x=1;//第几个
for(list_next* i=head;i!=NULL;i=i->next,x++)
{if(x == p){...}
}

将第tmp的next=第p个的next:

​​​​​​​

将第p个的next变为tmp:

​​​​​​​就好了:

tmp->next = i->next;
i->next=tmp;
break;//省时

最后是size++;

void add_node(list_next* head,int p,int v,list_next* &tail,int &size)
{if(p == 0){head_add(head,v,size);} if(p == size){tail_add(tail,v,size);return ;}list_next* tmp=new list_next;tmp->value = v;int x=1;for(list_next* i=head;i!=NULL;i=i->next,x++){if(x == p){tmp->next = i->next;i->next=tmp;break;}}size++;
}

然后是最简单的改值:

没啥好说:

void change(list_next* head,int p,int v)
{int x=1;for(list_next* i=head;i!=NULL;x++,i=i->next){if(x == p)//找到第p个值 {i->value=v;//改值 break;}}
}

随后是删头:

永恒的那张图:

​​​​​​​

我们可以直接把头变成头的next。

void head_del(list_next* &head,int &size)
{head = head->next;size--;
}

 一定要注意(size--) 

删中间:

函数定义:

void del_node(list_next* &head,int p,list_next* &tail,int &size)

加速代码:

if(p == 1)
{head_del(head,size);return ;
}

永恒之图:

先找到第p-1个,再把第p-1个的next变为第p个的next(也就是第p-1的next的next)。

但是,如果删尾部的话要有个特判,把第p-1个的next设为NULL,tail = 第p-1个。

然后:

就ok了。

void del_node(list_next* &head,int p,list_next* &tail,int &size)
{if(p == 1){head_del(head,size);return ;}int x=1;for(list_next* i=head;i!=NULL;i=i->next,x++){if(x == p-1){if(p == size)//如果删尾巴的话 {i->next = NULL;//那么这个就是尾巴,next是NULL tail = i;//尾巴变成i break;}i->next = i->next->next;break;}}size--;
}

这时所有的链表操作都好了,上总体代码。

#include"list.h"
using namespace std; 
void head_add(list_next* &head,int v,int &size)
{list_next* tmp=new list_next;tmp->value=v;tmp->next=head;head = tmp;size++;
}
void tail_add(list_next* &tail,int v,int &size)
{list_next* tmp=new list_next;tmp->value=v;tmp->next=NULL;tail -> next=tmp;tail = tmp;size++;
}
void add_node(list_next* head,int p,int v,list_next* &tail,int &size)
{if(p == 0){head_add(head,v,size);} if(p == size){tail_add(tail,v,size);return ;}list_next* tmp=new list_next;tmp->value = v;int x=1;for(list_next* i=head;i!=NULL;i=i->next,x++){if(x == p){tmp->next = i->next;i->next=tmp;break;}}size++;
}
void change(list_next* head,int p,int v)
{int x=1;for(list_next* i=head;i!=NULL;x++,i=i->next){if(x == p)//找到第p个值 {i->value=v;//改值 break;}}
}
void head_del(list_next* &head,int &size)
{head = head->next;size--;
}
void del_node(list_next* &head,int p,list_next* &tail,int &size)
{if(p == 1){head_del(head,size);return ;}int x=1;for(list_next* i=head;i!=NULL;i=i->next,x++){if(x == p-1){if(p == size)//如果删尾巴的话 {i->next = NULL;//那么这个就是尾巴,next是NULL tail = i;//尾巴变成i break;}i->next = i->next->next;break;}}size--;
}

末尾:

细心的小朋友会发现:我再list.h还写了一个struct,make_list,这个结构体包含了一条链表所要的基本属性(头,尾,长度)所以我写了一个初始化函数:

void init(list_make &p,int v)
{p.head=new list_next;p.tail=new list_next;p.head->value = v;p.head->next = NULL;p.tail = p.head;p.size = 1;
}

最后:listfun.h的代码应是:

#include"list.h"
using namespace std; 
void head_add(list_next* &head,int v,int &size)
{list_next* tmp=new list_next;tmp->value=v;tmp->next=head;head = tmp;size++;
}
void tail_add(list_next* &tail,int v,int &size)
{list_next* tmp=new list_next;tmp->value=v;tmp->next=NULL;tail -> next=tmp;tail = tmp;size++;
}
void add_node(list_next* head,int p,int v,list_next* &tail,int &size)
{if(p == 0){head_add(head,v,size);} if(p == size){tail_add(tail,v,size);return ;}list_next* tmp=new list_next;tmp->value = v;int x=1;for(list_next* i=head;i!=NULL;i=i->next,x++){if(x == p){tmp->next = i->next;i->next=tmp;break;}}size++;
}
void change(list_next* head,int p,int v)
{int x=1;for(list_next* i=head;i!=NULL;x++,i=i->next){if(x == p)//找到第p个值 {i->value=v;//改值 break;}}
}
void head_del(list_next* &head,int &size)
{head = head->next;size--;
}
void del_node(list_next* &head,int p,list_next* &tail,int &size)
{if(p == 1){head_del(head,size);return ;}int x=1;for(list_next* i=head;i!=NULL;i=i->next,x++){if(x == p-1){if(p == size)//如果删尾巴的话 {i->next = NULL;//那么这个就是尾巴,next是NULL tail = i;//尾巴变成i break;}i->next = i->next->next;break;}}size--;
}
void init(list_make &p,int v)
{p.head=new list_next;p.tail=new list_next;p.head->value = v;p.head->next = NULL;p.tail = p.head;p.size = 1;
}

oh,对了:

附上一句话和代码:遍历链表元素时:

for(list_next* i=head;i!=NULL;i=i->next)

i就是当前链表的其中一个的元素

相关文章:

手写单链表(指针)(next域)附图

目录 创建文件&#xff1a; 具体实现&#xff1a; 首先是头插。 注意&#xff1a;一定要注意&#xff1a;再定义tmp时&#xff0c;要给它赋一个初始值&#xff08;推荐使用 new list_next) 接着是尾插&#xff1a; 随后是中间插&#xff1a; 然后是最简单的改值&#xf…...

关于with torch.no_grad:的一些小问题

with torch.no_grad:是截断梯度记录的&#xff0c;新生成的数据的都不记录梯度&#xff0c;但是今天产生了一点小疑惑&#xff0c;如果存在多层函数嵌入&#xff0c;是不是函数内所有的数据都不记录梯度&#xff0c;验证了一下&#xff0c;确实是的。 import torch x torch.r…...

大创项目推荐 深度学习 机器视觉 人脸识别系统 - opencv python

文章目录 0 前言1 机器学习-人脸识别过程人脸检测人脸对其人脸特征向量化人脸识别 2 深度学习-人脸识别过程人脸检测人脸识别Metric Larning 3 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 人脸识别系统 该项目…...

【PostGIS】空间数据库-常用空间函数

记录一些常用的空间函数&#xff1a; 1、转换函数 在几何图形和外部数据格式之间进行转换的函数。 -- 将文本表示转换为几何类型 -- 结果&#xff1a;0101000000000000000000F03F000000000000F03F SELECT st_geomfromtext(point(1 1),0);-- 将几何类型转换为文本表示 -- 结果…...

程序员的50大JVM面试问题及答案

文章目录 1.JDK、JRE、JVM关系&#xff1f;2.启动程序如何查看加载了哪些类&#xff0c;以及加载顺序&#xff1f;3. class字节码文件10个主要组成部分?4.画一下jvm内存结构图&#xff1f;5.程序计数器6.Java虚拟机栈7.本地方法栈8.Java堆9.方法区10.运行时常量池&#xff1f;…...

架构设计系列之前端架构和后端架构的区别和联系

前端架构和后端架构都是软件系统中最关键的架构层&#xff0c;负责处理不同方面的任务和逻辑&#xff0c;两者之间是存在一些区别和联系的&#xff0c;我会从以下几个方面来阐述&#xff1a; 一、定位和职责 前端架构 主要关注用户界面和用户体验&#xff0c;负责处理用户与…...

UE5 水材质注意要点

1、两个法线反向交替流动&#xff0c;可以去观感假的现象 2、水面延边的透明度低 3、增加水面延边的浪花 4、增加折射 折射要整体质量至少在High才有效果 改为半透明材质没有法线信息&#xff1f; 5、处理反射效果 勾选为true 找到这个放在水域 勾为false&#xff0c;即可有非…...

数据安全扫描仪荣膺网络安全优秀创新成果大赛优胜奖 - 凸显多重优势

近日&#xff0c;由中国网络安全产业联盟&#xff08;CCIA&#xff09;主办、CCI数据安全工作委员会中国电子技术标准化研究院等单位承办的“2023年网络安全优秀创新成果大赛”获奖名单公布。天空卫士数据安全扫描仪&#xff08;DSS&#xff09;产品获得创新成果大赛优胜奖。 本…...

数据结构学习 leetcode64最小路径和

动态规划 题目&#xff1a; 建议看这里&#xff0c;有这道题详细的解析。我觉得写的挺好。 这是我在学动态规划的时候&#xff0c;动手做的一道题。 虽然我在学动态规划&#xff0c;但是我之前学了dps&#xff0c;所以我就想先用dps试着做&#xff0c;结果发现不行&#xf…...

导出(导入)Linux虚拟机并修改IP地址

一、导出虚拟机 说明&#xff1a;先关闭虚拟机&#xff0c;然后再进行导出。 步骤1&#xff1a;选择要导出的虚拟机 步骤2&#xff1a;选择文件菜单栏下的导出为OVF文件。 步骤3&#xff1a;将导出的文件保存至硬盘文件夹。 二、导入虚拟机 步骤1&#xff1a;选择文件菜单栏…...

OpenCV4工业缺陷检测的六种方法

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…...

ICC2:Less than minimum edge length和Concave convex edge enclosure

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 首先,要介绍一下这两种drc Less than minimum edge length对应的tf rule如下: 而Concave convex edge enclosure对应图示和tf 规则如下,可...

RouterSrv-DHCP

2023年全国网络系统管理赛项真题 模块B-Windows解析 题目 安装和配置DHCP relay服务,为办公区域网络提供地址上网。DHCP服务器位于AppSrv服务器上。拆分DHCP服务器上的作用域,拆分的百分比为7:3。InsideCli优先从RouterSrv获取地址。配置步骤 安装和配置DHCP relay服务,为办…...

【人生苦短,我学 Python】(8)文件的读写和过滤器

目录 简述 / 前言1. 文件的操作2. 过滤器2.1 more —— 逐屏显示数据2.2 sort —— 排序2.3 more 和 sort 一起用 文章传送门 简述 / 前言 上一篇我们介绍了 Python 的输入&#xff08;input&#xff09;和输出&#xff08;print&#xff09;&#xff0c;以及如何通过命令行给…...

智能优化算法应用:基于饥饿游戏算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于饥饿游戏算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于饥饿游戏算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.饥饿游戏算法4.实验参数设定5.算法结果6.…...

leetCode算法—10. 正则表达式匹配

10.给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 难度&#xff1a;困难 *** 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ‘*’ 匹…...

Android Studio 实现音乐播放器

目录 一、引言 视频效果展示&#xff1a; 1.启动页效果 2.登录页效果 3.注册页效果 4.歌曲列表页效果 5.播放页效果 二、详细设计 1.登陆注册功能 2.音乐列表页面 2.音乐播放功能 三、源码获取 一、引言 Android初学者开发第一个完整的实例项目应该就属《音乐播放器…...

端口占用命令 netstat (centos)+netstat (windows)

linux 1.使用 netstat 命令查看端口占用情况 netstat -tlnp 使用 -p 选项查看进程信息。 使用 -t 选项列出 TCP 协议的连接&#xff1a;类似&#xff08;使用 -u 选项列出 UDP 协议的连接&#xff1a;&#xff09; 2.查找占用指定端口号的应用信息 netstat -tlnp | grep 3…...

Python-基于fastapi实现SSE流式返回(类似GPT)

最近在做大模型对话相关功能&#xff0c;需要将对话内容流式返回给前端页面&#xff08;类似GPT的效果&#xff09;。下面直接说下如何实现&#xff1a; 1.首先导入fastapi和sse流式返回所需要的包 from fastapi import APIRouter, Response, status from sse_starlette.sse …...

iOS中宿主APP与录屏扩展进程数据传递方式

背景 在iOS生态系统中&#xff0c;应用程序的功能不再局限于单一的宿主应用&#xff0c;而是可以通过扩展进程实现更丰富的用户体验和功能。其中一种引人注目的扩展是录屏功能&#xff0c;它使用户能够捕捉设备屏幕上的活动&#xff0c;无论是游戏过程、教育演示还是其他应用场…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...

运行vue项目报错 errors and 0 warnings potentially fixable with the `--fix` option.

报错 找到package.json文件 找到这个修改成 "lint": "eslint --fix --ext .js,.vue src" 为elsint有配置结尾换行符&#xff0c;最后运行&#xff1a;npm run lint --fix...