了解Ruby中的链接列表数据结构

如果您熟悉数据结构,则可能听说过LinkedList

在本文中,我们将从头开始创建一个LinkedList,并说明此数据结构如何工作以及它的用途。

让我们首先说明链接列表的概念。

简单来说,LinkedList是一种由数据集合组成的数据结构。

LinkedList中的值表示节点,每个节点包含一个指向下一个节点的指针。 在LinkedList中,每个节点的数据可以是任何数据。 我们称第一个节点为头,最后一个为尾。

此数据结构类似于数组,因为我们可以将两者都用于存储线性数据。 尽管它们之间存在一些差异,但让我们深入研究它。

首先,在LinkedList中,检索元素的Big O时间复杂度为0(n)。 原因是,对于链表,我们无法像数组一样通过索引来检索元素。

我们需要从头开始遍历该列表,直到找到要检索的元素。

此时,您可能会认为最好使用数组而不是LinkedList。 因为我们在使用数组访问元素时具有更好的运行时复杂性。

现在让我们谈谈删除和插入。

数组中的这些操作消耗大量时间。 另一方面,LinkedList中这些操作的执行速度很快。 同样,数组的大小固定,链接列表是动态的,可以扩展其大小。
最终,链表需要比数组更少的内存空间。

现在,我们准备开始实施链接列表…

首先,我们将创建节点类,该类将帮助我们将新节点追加到“链接”列表中。

class Node
  attr_accessor :value , :next_node
 
  def initialize (value, next_node = nil )
    @value = value
    @next_node = next_node
  end
end

现在我们有了Node类,我们可以创建LinkedList类。

class LinkedList
  attr_accessor :tail , :head
  def initialize
    @head = nil
    @tail = nil
  end
end

对于我们的LinkedList类,我们还定义了两个访问器(tail,head)。 头部将是LinkedList中的第一个元素,而尾部将是最后一个元素。

我们还使用了构造函数方法来分配初始值。

这是创建LinkedList的基本设置,要对其进行测试,我们可以创建LinkedList类的实例。

list = LinkedList . new
puts list

然后在控制台中运行我们的ruby文件并查看输出。

user@PC/desktop/ Ruby: ~$ ruby linked_list.rb
#<LinkedList:0x00000000051ff9a0>

现在,我们可以创建第一个方法来向LinkedList添加新元素。 我们将从添加add_first方法开始。

def add_first (data)
  @head = Node.new(data, @head)
end

现在,通过这种方法,我们可以在LinkedList的开头添加元素。 由于我们将@head设置为新节点,因此我们将数据和@head传递为第二个参数。 结果是该元素将被插入列表的第一个位置。

现在创建一个新方法,将其追加到列表的末尾。

def add_last (data)
  node = Node.new(number)
  if !@head
    @head = node
    @tail = node
    return
  end
  last_node = get_last()
  last_node.next_node = node
  @tail = node
end

private

def get_last
  return if !@head
  node = @head
  until node.next_node. nil ?
    node = node.next_node
  end
  return node
end

在这种情况下,我们有两种方法。 一个有助于获取最后一个节点,该节点是私有的,另一个则将节点添加到列表的末尾。 在第一种方法中,我们首先创建一个新节点并传递数据。

然后,我们检查@head是否为nil,是否将@head和@tail设置为新节点并返回,以便执行停止。 如果@head不为nil,则通过调用get_last方法获得最后一个节点。 然后将next_node设置为新节点,最后,我们将该节点分配给@tail。

很好,现在我们可以将新元素添加到列表的末尾和前面。 但是我们可以通过创建将元素追加到特定位置的方法来做得更好,让我们看看如何做到这一点。

def add_at (index, data)
 if !@head
   @head = Node.new(data)
   return
 end
 if index == 0
   add_first(data)
   return
 end
 
 previous = get_node(index — 1 ) || get_last()
 node = Node.new(data, previous.next_node)
 previous.next_node = node
end

private

def get_node (index)
  return if !@head
  return @head if index === 0
 
  node = @head
  counter = 0
  until node.next_node. nil ?
    node = node.next_node
    counter+= 1
    return node if counter === index
  end
end

同样,这里还有另一个私有方法,可以帮助我们在特定索引处获取节点。 在add_at方法中,我们获取索引和数据,如果@head为零 ,则将@head分配给新节点。 然后返回以停止执行。 如果 @head不为nil,则检查索引是否等于0,如果索引为0,则调用add_first方法并传递数据。 这样,我们就可以重用始终是一个好习惯的方法。

然后,如果索引不为0,则创建一个名为previous的变量,并将其分配给get_node或get_last方法的结果值。 如果其中一个返回nil,则前一个变量将采用另一个方法的值。 然后,我们创建一个新节点并将数据和previous.next_node作为第二个参数传递。 最后,我们将previous.next_node分配给刚创建的节点。

现在我们基本上可以将元素添加到列表中的任何特定位置了。

我们将执行相同的操作以删除元素。 我们将使用三种方法remove_firstremove_lastremove_at

def remove_first
  return nil if !@head
  @head = @head.next_node
end

def remove_last
  return nil if !@head
  if !@head.next_node
    @head = nil
    return
  end
  
  prev = @head
  node = @head.next_node
  while node.next_node do
    node = node.next_node
    prev = prev.next_node
  end
  @tail = prev
  prev.next_node = nil
end

def remove_at (index)
  return if !@head
  if index == 0
    @head = @head.next_node 
    return
  end
  
  previous = get_node(index- 1 )
  if !previous || !previous.next_node
    return
  end
  previous.next_node = previous.next_node.next_node
end

这三种方法遵循与我们过去附加的逻辑相同的逻辑。 唯一的区别是操作(删除/添加)。

最后,我们想要获取第一个元素,清除我们的LinkedList并获取大小,让我们放置这些方法。

def clear
  @head = nil
  @tail = nil
end

def size
  return 0 if !@head
  node = @head
  counter = 0
  while node do
    node = node.next_node
    counter += 1
  end
  counter
end

def get_first
  @head.value
end

在clear方法中,我们只将@head和@tail分配给nil。 满容易。 在get_first方法中,我们返回@head的值。 在size方法中,我们遍历头部并创建一个计数器,直到节点为nil,然后返回该计数器。 真的也很简单。

太棒了,我们已经用不同的方法实现了链表数据结构。

从那以后,LinkedList是一个很棒的数据结构,可以在计算机中实现。 也有队列和堆栈。 了解它的工作原理非常重要,因为许多应用程序使用链表来存储数据,因为它们可以执行数组无法执行的恒定操作。

在此处查看LinkedList的不同用法。

在现实世界中,数据结构使用的内存空间可能会确定巨大的变化。 这就是为什么LinkedList在某些情况下如此有用的原因。 重要的是要知道在某些情况下使用数组更好,因此一切都取决于您的需求。

希望您喜欢并学到一些新东西,如果喜欢可以分享这篇文章,并感谢您的阅读。

From: https://hackernoon.com/understanding-linkedlist-data-structure-in-ruby-4q653yqo

【Tableau】解决订阅报表PDF中文显示为乱码(方框)问题 一、问题描述 在tableau server网页端报表中文字符能正常显示,但在订阅后发送到邮箱时,以图片格式呈现的内容中中文字符显示为方框。 网页端报表能正常显示中文字符: 邮件中的报表不能正常显示中文字符: 二、问题分析 网页端字符显示情况是由html编码决定的,而tableau生成图片时是通过所部署的服务器的字体文件显示字体。因此可能是由于Linux服务器缺失相关的字体文件导致网页端选择的中文字体在服务器上缺失对应的字体文件导致的。则考虑在服务器引入对应的字体文件。 三、问题解决 1、查看服务器现有 阅读详情

相关推荐

一文读懂水利无人机AI识别算法,概念、需求、解决方案

复亚智能的水利无人机AI识别算法通过先进的技术手段,为水利管理提供了高效、精准的解决方案。随着技术的不断进步和应用的深入,复亚智能的解决方案将在更多水利场景中发挥重要作用,助力智慧水利管理的全面升级。该系统通过搭载在无人机上的传感器和摄像头,结合先进的AI识别算法,实现对河道淤积、漂浮物、船只和水质污染等问题的自动检测和监控。基于大量实飞采集的数据,复亚智能的算法经过严格的训练,能够准确识别各种水利问题。复亚智能的系统具有高度的开放性和兼容性,能够第三方平台和算法无缝对接,满足不同客户的多样化需求。

foiadrone的博客 1173

Ruby 数组操作(和 Python3 列表+元组+集合 对比)

本来是想写到 Ruby 学习笔记一块的,但是数组操作这块的内容也太多了,Ruby 里没有单独的集合的概念,或许是因为数组就已经涵盖了这些了。所以单独提取出来了。所以,话不多说,直接上菜(为了对比明显,Ruby 中尽量去掉括号)! 数组内建方法 # Ruby [20] pry(main)> names = Array.new => [] [22] pry(main)> names = Array.new(10) => [nil, nil, nil, nil, nil, nil,

Looking的网页备忘录和个人知识库 1469

list:Ruby 中的列表

列表Ruby 中列出。 List是一类包装单链表。 它可以和Array一样使用。 但处理速度不同。 用法 所有接口 Array 类相同。 > Array.methods - List.methods => [] > Array.new.methods - List.new.methods => [] 可以使用列表代替数组。 require 'list' list = List . new # or List[] list . push 1 , 2 , 3 list . pop #=> 3 list [ 0 , 2 ] #=> List[1,2] list [ 0 , 1 ] = 5 list . each do | i | puts i #=> 5,2 end puts List [ 1 , 2 , 3 ] . map { | i | i * i } . injec

linkedlist结构_了解Ruby中的LinkedList数据结构

linkedlist结构 如果您熟悉数据结构,则可能听说过LinkedList 。 在本文中,我们将从头开始创建一个LinkedList,并说明此数据结构如何工作以及它的用途。 让我们首先说明一个链表的概念。 简单来说,LinkedList是一种由数据集合组成的数据结构。 LinkedList中的值表示节点,每个节点包含一个指向下一个节点的指针。 在LinkedList中,...

编程故事的地方 256

公共后缀列表Ruby实现指南

公共后缀列表(Public Suffix List, PSL)是一个维护互联网域名体系中有效“公共”部分的列表。这个项目,[weppos/publicsuffix-ruby](https://github.com/weppos/publicsuffix-ruby),是Ruby语言对这一标准的实现,允许开发者轻松地处理Cookie等机制中的域名分割问题,确保遵循正确的隐私和安全策略。通过利用此库,您

gitblog_00528的博客 720

公共后缀列表解析库:PublicSuffix-Ruby

PublicSuffix-Ruby 是一个基于Ruby编写的域名解析库,它利用了公共后缀列表(Public Suffix List)来高效地处理域名。这个开源工具由Simone Carletti开发并维护,遵循MIT许可协议。项目致力于提供一种准确且跨平台的方法,帮助开发者解析复杂的互联网域名结构。 ## 核心功能 PublicSuffix-Ruby的主要能力包括: - **域名解析**:能够从

gitblog_00077的博客 924

ruby elixir_将Elixirruby和javascript语法进行比较

ruby elixirI have been writing Elixir full-time for about a year, but I came to it from Ruby. As you probably know, Elixir was created by a former Ruby developer, José Valim, and his idea was to keep ...

weixin_26643379的博客 185

Twitter列表管理终极指南:使用twitter-ruby创建、订阅和分享列表的完整教程

Twitter列表是组织和关注特定用户群体的强大工具,而twitter-ruby库提供了完整的API接口来管理这些列表。无论你是想要创建技术专家列表、新闻源还是兴趣小组,本教程将带你掌握使用twitter-ruby进行Twitter列表管理的所有核心功能。💪 [![Twitter列表管理概念图](https://raw.gitcode.com/gh_mirrors/tw/twitter-rub

gitblog_00161的博客 435

Ruby on Rails,通过页面链接向Controller中传递参数,附赠调试技巧

http://blog.csdn.net/abbuggy/article/details/7636462 《Ruby on Rails,通过建立页面导航链接实现页面跳转》中,我们了解到如何通过link_to(text,target)方法在Templates中定义连接。其中参数target以填入了两个最终要的参数,Controller和Action。如果有一个分页显示的列表,我们希望希望查看其

边晓宇@CSDN 1万+

如何使用 Ruby-Build:从入门到精通的 Ruby 版本管理工具指南

Ruby-Build 是一款强大的命令行工具,专为在类 Unix 系统上从源代码下载、编译和安装任何 Ruby 版本而设计。它既可以作为 rbenv 插件通过 `rbenv install` 命令使用,也能作为独立程序以 `ruby-build` 命令运行,是 Ruby 开发者管理多版本环境的必备工具。 ## 快速安装 Ruby-Build 的三种方法 ### Homebrew 一键安装(推荐

gitblog_00725的博客 803

vscode-ruby调试功能详解:轻松解决Ruby程序中的bug

vscode-ruby是一款为Visual Studio Code提供Ruby语言支持和调试功能的强大扩展,能帮助开发者轻松定位并解决Ruby程序中的各类bug。通过其直观的调试界面和丰富的功能,即使是新手也能快速掌握Ruby程序的调试技巧。 ## 一、调试环境准备:三步轻松配置 ### 1.1 安装必要的Ruby依赖 要启用vscode-ruby的调试功能,首先需要安装`ruby-debu

gitblog_00715的博客 318

基本的ruby语法

基本的ruby语法1.1      变量、常量和类型1)      定义变量变量类型描述示例局部变量(或伪变量)以小写字母或下划线卡头var    _var全局变量以$开头$var类变量类中定义,以@@开头@@var

keymanjun的专栏 388

Ruby操纵数据结构(四)

 8、转换哈希表为数组 要转换整个哈希表为一个数组,使用to_a方法。在结果数组中,键将被做为奇数元素(从零开始),值将被做为数组的偶数元素: h = { "a"=>1,"b"=>2} h.to_a # ["a",1,"b",2] 也可以只转换键或值到一个数组中: h.keys # ["a","b"] h.values # [1,2] 最后,你可以以键的列表为基础从数组中取出值,这要使用i

lee576的专栏 3189

Ruby语言的链表排序

Ruby中,我们可以自定义一个简单的链表节点类。链表节点通常包含数据部分和指向下一个节点的指针。以下是一个链表节点的实现:```rubyendend```在这里,我们创建了一个ListNode类,包含一个值(value)和一个指向下一个节点的引用(next_node当我们需要构建链表时,我们可以使用这个节点类。本文探讨了链表在Ruby语言中的基本实现以及如何对其进行排序。我们介绍了几种常见的排序算法,包括冒泡排序、选择排序和归并排序,演示了它们在链表上的实现。

2501_91366435的博客 431

Ruby 2.x 源代码学习:语法分析 & 中间代码生成 之 指令链表序列化

前言 回顾一下 Ruby 解释器处理流程 词法分析 语法分析 AST 生成 虚拟机指令生成 虚拟机指令有两种存储结构: 链式结构,通过 LINK_ELEMENT 链表节点 数组(线性)结构 解释器会先遍历 AST 生成链式结构存储的指令列表,但是虚拟机并不会直接解释执行该列表,而是进一步将指令列表“序列化”成字节数组,PC(指令指...

weixin_33840661的博客 189

Ruby on Rails全栈课程】2.8 ruby数据结构--哈希(Hash)

1、哈希(Hash) 哈希也是存储对象的一个集合,哈希里面的元素是以&amp;quot;key&amp;quot; =&amp;amp;gt; “value”(键值对)这样的形式存在的,元素是没有顺序的,哈希的键可以是任意对象,键必须的唯一的,键通常用符号(Symbol)表示。 哈希的创建有两种形式,两种形式都是一样的,最常使用第二种: irb(main):108:0&amp;amp;gt; hash_1 = {:name =&amp;amp;gt; &amp

腾讯云云开发布道师,慕课网合作讲师 773

Ruby操纵数据结构(二)

Ruby操纵数据结构(二) 8、实现稀疏矩阵 有时候我们需要被定义元素很少的数组;它的其余元素可以末被定义(或者通常为零)。这称为稀疏矩阵,历史上它是消耗内存的大户,以致让人们寻找一些间接的方法来实现它。 当然,大多数情况下,Ruby数组足够有效了,因

lee576的专栏 2404

《基于YOLOv8的港口船舶缆绳系泊状态监测系统》(包含源码、可视化界面、完整数据集、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!!项目备注1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

上一篇: ES2020:新功能摘要和示例
下一篇: linkedlist结构_了解Ruby中的LinkedList数据结构
dfsgwe1231
博客等级 码龄12年 195粉丝 0原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值