Ruby有堆栈,队列,链表,地图或集合等容器吗?

Cha*_*han 53 ruby

我在网上检查了几个Ruby教程,他们似乎都在使用数组.那么如何在Ruby中实现以下数据结构呢?

  • 堆栈
  • 队列
  • 链接列表
  • 地图

Jam*_*mes 86

(从评论中移出)

好吧,通过将自己限制为堆栈或队列方法(推,弹,移位,非移位),数组可以是堆栈或队列.使用push/pop提供LIFO(后进先出)行为(堆栈),而使用push/shift或unshift/pop给出FIFO行为(队列).

地图是 哈希值,Set类已经存在.

您可以使用类实现链接列表,但是数组将使用标准数组方法提供类似链接列表的行为.

  • Array类存储索引到数组中使用的第一个元素.调用Array :: Shift会递增索引,因此它在O(1)时间内运行(实际上没有任何移位).Array :: Push在O(1)中运行,除非数组已满,在这种情况下,它需要创建一个具有更多容量的新数组并复制原始数组.源代码:https://github.com/ruby/ruby/blob/trunk/array.c. (23认同)
  • 是的,数组*可以这样使用,但是当调用链表时,它不是那么慢吗? (6认同)
  • @MichaelVenable 你的评论应该是这个答案的一部分;我知道 shift/unshift 和 push/pop,但是在想要例如 deque 的上下文中了解它们是没有用的,除非您也知道实现的效率足以在实践中使用。 (3认同)
  • @scaryguy:回顾我之前的评论,我想我实际上是在谈论“Array::Shift”。在使用数组作为队列的情况下(我回复的答案中提到的用例),[shift](https://github.com/ruby/ruby/blob/f6f388a5bdbd3d3a68bf18f3352ba2be12688639/array.c#L981) 看起来让我在 O(1) 中运行。我不认为 `unshift` 在这里是相关的,因为它不需要实现堆栈或队列,答案中引用的两个数据结构。 (2认同)

div*_*yum 32

我猜大部分内容都包含在上面的答案中,但仅仅是为了更好地解释它的总结:

堆:

stack = []
stack << 2 # push 2 => stack = [2]
stack << 3 # push 3 => stack = [2, 3]
stack.pop  # pop => 3, stack = [2]
Run Code Online (Sandbox Code Playgroud)

队列:

# we have a Queue class
queue = Queue.new
queue << 2 # push 2 => queue = [2]
queue << 3 # push 3 => queue = [2, 3] (just a representation, it will be an object though)
queue.pop # pop 2
Run Code Online (Sandbox Code Playgroud)

链接列表:

# A very simple representation
class Node
  attr_accessor :value, :next_node

  def initialize(value, next_node=nil)
    @value = value
    @next_node = next_node
  end
end

class LinkedList

  def initialize(value)
    @head = Node.new(value)
  end

  def add(value)
    current = @head
    while !current.next_node.nil?
      current = current.next_node
    end
    current.next_node = Node.new(value)
  end
end

ll = LinkedList.new
ll.add(10)
ll.add(20)
Run Code Online (Sandbox Code Playgroud)

地图:

# Hash incase of ruby
a = {} (or a = Hash.new)
a['one'] = 1 # a = {"one"=>1}
a['two'] = 2 # a = {"one"=>1, "two"=>2}
Run Code Online (Sandbox Code Playgroud)

组:

# we have a Set class
require 'set'
s = Set.new         # <Set: {}>
s.add(1)            # <Set: {1}>
s.add(2)            # <Set: {1, 2}>
s.add(1)            # <Set: {1, 2}>
s.instance_of?(Set) # true
Run Code Online (Sandbox Code Playgroud)


mip*_*adi 8

是的,虽然没有明确的名义.的Array类可被用作一个堆栈,队列或链表.例如,pushpop使其行为像堆栈.Ruby Map就是这个Hash类.Ruby也有一个Set类,虽然你必须导入一个模块来使用它(require 'set').


fro*_*001 5

Ruby语言实际上有一个Queue类,可以用作....等待它...一个队列;)

它是线程安全的,易于使用.

@James的其余部分答案非常准确.

  • 现在甚至还有一个“SizedQueue”。 (2认同)