Go的数据结构与实现【LinkedList】
介绍
所谓链表(Linked List),就是按线性次序排列的一组数据节点。每个节点都是一个对象,它通过一个引用指向对应的数据元素,同时还通过一个引用next指向下一节点。
实现
逻辑方法
我们定义链表的结构体:
// LinkedList the linked list struct
type LinkedList struct {sync.RWMutexhead *Nodesize int
}// Node a single node that composes the list
type Node struct {content Tnext *Node
}
其中包含头节点和链表长度,在这里我们主要实现以下方法:
- Add:添加一个元素到链表末尾
- Insert:向链表指定位置插入元素
- RemoveAt:移除指定索引位置的元素
- IndexOf:取指定索引位置的元素
- IsEmpty:判断链表是否为空
- Size:获取链表长度
- Traverse:遍历链表并输出
首先是Add方法,判断链表头节点是否为空,若空则设置头节点为插入的元素,若非空,找到链表末尾节点,再插入元素。
// Add adds t to the end of the linked list
func (l *LinkedList) Add(t T) {l.Lock()defer l.Unlock()node := NewNode(t)if l.head == nil {l.head = node} else {last := l.headfor {if last.next == nil {break}last = last.next}last.next = node}l.size++
}
Insert方法,注意判断索引位置是否合法,再插入指定位置。
// Insert adds t at position pos
func (l *LinkedList) Insert(t T, pos int) error {l.Lock()defer l.Unlock()// validate positionif pos < 0 || pos > l.size {return fmt.Errorf("insert position must be larger than 0 and smaller than linked list size")}node := NewNode(t)if pos == 0 {node.next = l.headl.head = nodereturn nil}head := l.headidx := 0for idx < pos-2 {idx++head = head.next}node.next = head.nexthead.next = nodel.size++return nil
}
RemoveAt方法与之类似,判断索引位置是否合法再移除。
// RemoveAt removes a node at position pos
func (l *LinkedList) RemoveAt(pos int) (*T, error) {l.Lock()defer l.Unlock()// validate positionif pos < 0 || pos > l.size {return nil, fmt.Errorf("insert position must be larger than 0 and smaller than linked list size")}head := l.headidx := 0for idx < pos-1 {idx++head = head.next}next := head.nexthead.next = next.nextl.size--return &next.content, nil
}
剩下的方法直接取相应数据即可。
// IndexOf returns the position of the t
func (l *LinkedList) IndexOf(t T) int {l.RLock()defer l.RUnlock()head := l.headidx := 0for {if head.content == t {return idx}if head.next == nil {return -1}head = head.nextidx++}
}// IsEmpty returns true if the list is empty
func (l *LinkedList) IsEmpty() bool {l.RLock()defer l.RUnlock()return l.head == nil
}// Size returns the linked list size
func (l *LinkedList) Size() int {l.RLock()defer l.RUnlock()return l.size
}
遍历方法Traverse还会输出元素内容。
// Traverse traverses linked list
func (l *LinkedList) Traverse() {l.RLock()defer l.RUnlock()head := l.headfor {if head == nil {break}head.Print()head = head.next}fmt.Println()
}
单元测试
单元测试如下:
import "testing"var (t1 T = 1t2 T = 2t3 T = 3t4 T = 4
)func InitLinkedList() *LinkedList {list := NewLinkedList()list.head = NewNode(t1)list.head.next = NewNode(t2)list.head.next.next = NewNode(t3)list.size = 3return list
}func TestLinkedList_Add(t *testing.T) {linkedList := InitLinkedList()size := linkedList.Size()if size != 3 {t.Errorf("linked list size should be 3 but got %d", size)}linkedList.Add(4)size = linkedList.Size()if size != 4 {t.Errorf("linked list size should be 4 but got %d", size)}
}func TestLinkedList_Insert(t *testing.T) {linkedList := InitLinkedList()err := linkedList.Insert(t4, 1)if err != nil {t.Errorf("insert into linked list err %v", err)}idx1 := linkedList.IndexOf(t2)idx2 := linkedList.IndexOf(t4)if idx1 != 2 || idx2 != 1 {t.Errorf("linked list position is not expected.")}
}func TestLinkedList_RemoveAt(t *testing.T) {linkedList := InitLinkedList()ret, err := linkedList.RemoveAt(2)if err != nil {t.Errorf("linked list err %v", err)}if *ret != t3 {t.Errorf("removed item expect 3 but got %d", *ret)}size := linkedList.Size()if size != 2 {t.Errorf("linked list size should be 2 but got %d", size)}
}func TestLinkedList_IsEmpty(t *testing.T) {linkedList := InitLinkedList()empty := linkedList.IsEmpty()if empty {t.Errorf("linked list is not empty.")}linkedList = &LinkedList{}empty = linkedList.IsEmpty()if !empty {t.Errorf("linked list is empty.")}
}func TestLinkedList_Traverse(t *testing.T) {linkedList := InitLinkedList()linkedList.Traverse()
}
相关文章:
Go的数据结构与实现【LinkedList】
介绍 所谓链表(Linked List),就是按线性次序排列的一组数据节点。每个节点都是一个对象,它通过一个引用指向对应的数据元素,同时还通过一个引用next指向下一节点。 实现 逻辑方法 我们定义链表的结构体:…...
Ubuntu22.04安装CUDA+CUDNN+Conda+PyTorch
步骤: 1、安装显卡驱动; 2、安装CUDA; 3、安装CUDNN; 4、安装Conda; 5、安装Pytorch。 一、系统和硬件信息 1、Ubuntu 22.04 2、显卡:4060Ti 二、安装显卡驱动 (已经安装的可以跳过&a…...
当“广撒网”遇上“精准定点”的鱼叉式网络钓鱼
批量网络钓鱼电子邮件活动倾向于针对大量受众,它们通常使用笼统的措辞和简单的格式,其中不乏各种拼写错误。而有针对性的攻击往往需要付出更大的努力,攻击者会伪装成雇主或客户向目标发送包含个人详细信息的个性化消息。在更大范围内采用这种…...
svn ldap认证临时切换到本地认证
当前的svn是在CentOS 7 下 SVN、 Apache 对接 LDAP 服务实现用户账号管理和权限认证,本文模拟ldap数据丢失如何恢复svn,方法是临时将认证切换到本地认证 编辑subversion.conf文件 vi /etc/httpd/conf.d/subversion.conf 注释ldap-status #<Locati…...
极狐GitLab如何配置使用独立数据库?
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab :https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署…...
TCP状态转换详解
1.什么是TCP的状态转换 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议。在 TCP 连接的生命周期中,连接的状态会随着不同阶段的通信而发生变化,这些变化被称为状…...
SimMIM:一个类BERT的计算机视觉的预训练框架
1、前言 呃…好久没有写博客了,主要是最近时间比较少。今天来做一期视频博客的内容。本文主要讲SimMIM,它是一个将计算机视觉(图像)进行自监督训练的框架。 原论文:SimMIM:用于掩码图像建模的简单框架 (a…...
数据精度丢失
js数据精度丢失 最近看面试题想到了之前在开发钟遇到过的问题,现总结一下 在开发过程中,发现从后台返回的数据结构中的id字段在前端显示为不正确的值。经过排查,怀疑是JavaScript中Number类型精度丢失的问题。通过将id字段的类型从Number改为…...
Element UI DatePicker选择日期范围区间默认显示前一个月和本月
要求:点击el-date-picker选择时间范围时,默认展开当月和上个月。 但是Element UI的组件默认展开的是本月和下一个月,如下图所示: 改为 <span click"changeInitCalendarRange"><el-date-picker v-model"r…...
C++:聚合类、嵌套类、局部类、union类详细介绍与分析
聚合类 (1)What(什么是聚合类) 本质是一个自定义类型的数据结构(结构体或类),但聚合类有以下特性: 所有的成员都是public没有任何构造函数没有基类类内部没有初始值 (2)Why(聚合类的作用&…...
MKS流量计软件MFC通讯驱动使用于C和P系列MFC控制USB接口W10系统
MKS流量计软件MFC通讯驱动使用于C和P系列MFC控制USB接口W10系统...
C++:左值/右值引用、移动语义/std::move、万能引用/完美转发std::forward 详解
你能学到 左值 与 右值左值引用 与 右值引用 基本用法与作用拷贝构造函数 与 移动构造函数移动语义 与 std::move万能引用 与 引用折叠完美转发:std::forward 前言 本文代码片段中变量命名规则如下: 小写字母:一般类型的变量(非…...
蜂窝物联云平台:一站式服务,智能生活从此开始!
蜂窝云平台 一、PC端展示与管理 GIS地图整合 在GIS地图上精确展示地块,轻松点选查看详细设备信息、实时监控和控制功能,以及基地的全方位介绍。 个性化定制界面 界面布局与功能展示均可按需求定制,打造独一无二的用户体验。 数据集中看板 将…...
【中项】系统集成项目管理工程师-第3章 信息技术服务-3.3服务生命周期
前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…...
【iOS】——消息传递底层实现
消息传递是什么 Objective-C是一种动态类型语言,这意味着在编译时并不确定对象的具体类型,而是在运行时决定。消息传递机制允许程序在运行时向对象发送消息,对象再决定如何响应这些消息。 当你通过对象调用方法时,例如像这样[ob…...
PostgreSQL数据库从入门到精通系列之十:表空间、索引表空间、创建表空间、创建索引空间、创建分区表、创建分区表的分区、创建指定表空间、索引表空间的分区表
PostgreSQL数据库从入门到精通系列之十:表空间、索引表空间、创建表空间、创建索引空间、创建分区表、创建分区表的分区、创建指定表空间、索引表空间的分区表 一、数据库表空间和数据库之间的关系二、索引表空间和数据库之间的关系三、创建角色四、创建表空间目录五、创建表空…...
恶补,先验分布,后验分布 ,似然估计
恶补,打一遍增加印象 先验分布后验分布,似然估计 声明:仅记录个人学习,并无其他用途。 先验分布 后验分布, 似然估计 隔壁小哥的故事: 隔壁小哥要去15公里外的一个公园里玩,小哥可以选择步行…...
JS之数组中的reduce方法
文章目录 基本语法:callbackFn 的参数:例子1. 数组求和2. 数组求积3. 扁平化数组4. 数组元素计数5. 使用对象解构和展开运算符合并数组中的对象6. 求最大值和最小值 函数组合异步操作中的 reduce总结 reduce 是 JavaScript 中 Array 对象的一个方法,非常…...
在win10上通过WSL和docker安装Ubuntu子系统,并配置Ubuntu可成功使用宿主机GPU
本文主要记录win10系统上,通过WSL的Ubuntu系统以及Docker使用GPU的全部过程。 文章目录 1、 启用hyper-v2、 安装docker3、 安装WSL3.1 安装WSL23.1.1 检查是否安装了WSL23.1.1 安装和配置 WSL 23.2 安装Ubuntu 子系统3.3 检查并修改WSL版本4、docker配置ubuntu20.04 LTS5、下…...
python需要掌握那些语法
1-list数据类型 内置方法查看长度len(list) 2.array数据类型 查看形状 3.tuple 取出元组 t (1, 2, 3, 4, 5) # 取出第一个元素 2first_element t[0] 3print(first_element) # 输出:1 4 5# 取出第三个元素 6third_element t[2] 7pr…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
Canal环境搭建并实现和ES数据同步
作者:田超凡 日期:2025年6月7日 Canal安装,启动端口11111、8082: 安装canal-deployer服务端: https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...
