我是一名自学成才的程序员,并从Ruby开始。我目前正在尝试学习算法和数据结构,并注意到一些称为链表的东西。看起来Ruby没有那个数据结构(可能在Array?)。我熟悉数组和哈希。
您如何描述/解释来自我背景的人的链接列表是什么?
答案 0 :(得分:2)
链接列表相当简单:它们是通过将元素链接在一起而创建的列表。 (有点显而易见,当你想到它时,不是吗?)
在最基本的形式中,链表只是空或一对。该对的第一个元素是一个值,该对的第二个元素是一个表示其余值的链表。
传统上,该对称为 cons cell ,第一个元素称为 head 或 car 列表和第二个元素element被称为列表的 tail 或 cdr 。空列表名为Nil
或简称[]
。
这是Ruby中链接列表的一个非常简单的实现,它只使用函数来实现链接列表(以及布尔值和条件,而我们还在其中):
True = ->(iff, _) { iff }
False = ->(_, els) { els }
Pair = ->(first, rest) { -> x { x.(first, rest) }}
First = -> list { list.(True ) }
Rest = -> list { list.(False) }
在这里,我们有一个包含三个元素的简单列表:
List = Pair.(1, Pair.(2, Pair.(3, nil)))
First.(Rest.(List))
# => 2
更真实的面向对象的列表编码如下所示:
class List
def cons(el) Pair.new(el, self) end
Empty = new
class Pair < self
attr_reader :first, :rest
def initialize(first, rest=Empty)
self.first, self.rest = first, rest
end
private
attr_writer :first, :rest
end
end
同样,列表包含两个元素:
list1 = List::Pair.new(1, List::Pair.new(2, List::Pair.new(3, List::Empty)))
# corresponds to the list [1, 2, 3]
list1.rest.first
# => 2
list2 = List::Empty.cons(6).cons(5).cons(4)
# List[4, 5, 6]
list2.rest.first
# => 5
更完整和Rubyish的实现可能如下所示:
class List
include Enumerable
def self.[](*els) els.reverse_each.inject(Empty, &:cons) end
def cons(el) Pair[el, self] end
def prepend(prefix)
case
when empty? then prefix
when prefix.empty? then self
else prepend(prefix.rest).cons(prefix.first)
end
end
def to_s; "List[#{map(&:to_s).join(', ')}]" end
def inspect; "List[#{map(&:inspect).join(', ')}]" end
def each; return enum_for(__method__) unless block_given? end
class << Empty = new
def empty?; true end
alias_method :inspect, def to_s; 'Empty' end
freeze
end
Empty.freeze
class Pair < self
def initialize(first, rest=Empty)
self.first, self.rest = first, rest
freeze
end
def empty?; false end
def each(&blk)
return super unless block_given?
yield first
rest.each(&blk)
end
private
attr_writer :first, :rest
protected
attr_reader :first, :rest
class << self; alias_method :[], :new end
freeze
end
freeze
end
一些例子:
list1 = List::Pair[1, List::Pair[2, List::Pair[3, List::Empty]]]
# => List[1, 2, 3]
list2 = List::Empty.cons(6).cons(5).cons(4)
# => List[4, 5, 6]
list3 = List[7, 8, 9]
# => List[7, 8, 9]
list4 = list3.prepend(list2).prepend(list1)
# => List[1, 2, 3, 4, 5, 6, 7, 8, 9]
list4.partition(&:odd?)
# => [[1, 3, 5, 7, 9], [2, 4, 6, 8]]
答案 1 :(得分:1)
在计算机科学中,链表是由一组节点组成的数据结构,这些节点一起表示序列。在最简单的形式下,每个节点由数据和到序列中下一个节点的引用(换句话说,链接)组成;更复杂的变体添加其他链接。该结构允许从序列中的任何位置有效插入或移除元素。 http://en.wikipedia.org/wiki/Linked_list
以下是ruby的实现:http://matt.weppler.me/2013/08/14/implementing-a-linked-list-in-ruby.html
感谢Ruby学习我最喜欢的语言之一。