`
hideto
  • 浏览: 2650824 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

每天一条Ruby小道之高级数据结构

    博客分类:
  • Ruby
阅读更多
Set

初始化
require 'set'
s1 = Set[3,4,5]
arr = [3,4,5]
s2 = Set.new(arr)
s3 = Set.new(arr) {|x| x.to_s}

简单操作
x = Set[1,2,3]
y = Set[3,4,5]

a = x.union(y)   # Set[1,2,3,4,5]
b = x | y        # Set[1,2,3,4,5]
c = x + y        # Set[1,2,3,4,5]

d = x.intersection(y)   # Set[3]
e = x & y               # Set[3]

diff = x - y     # Set[1,2]

x.include?(2)    # true
x.include?(4)    # false
x.member?(2)     # true
x.member?(4)     # false

x.empty?         # false
x.clear
x.empty?         # true

x = Set[3,4,5]
y = Set[3,4]

x.subset?(y)         # false
y.subset?(x)         # true
y.proper_subset?(x)  # true
x.subset?(x)         # true
x.proper_subset?(x)  # false
x.superset?(y)       # true
x << 6               # Set: {3,4,5,6}
Set[3,4,5] == Set[5,4,3]  # true

高级操作
s = Set[1,2,3,4,5]
s.each {|x| puts x; break}  # Output: 5

files = Set.new(Dir["*"])
hash = files.classify do |f|
  if File.size(f) <= 10_000
    :small
  elsif File.size(f) <= 10_000_000
    :medium
  else
    :large
  end
end

small_files = hash[:small]
medium_files = hash[:medium]
large_files = hash[:large]

numbers = Set[1,2,3,4,5,6,7,8,9,0]
set = numbers.divide{|i| i % 2}
p set #<Set: {#<Set: {5, 1, 7, 3, 9}>,  #<Set: {0, 6, 2, 8, 4}>}>

Stack&Queue

Ruby没有实现Stack(LIFO)和Queue(FIFO)
Stack实现
class Stack

  def initialize
    @store = []
  end

  def push(x)
    @store.push x
  end

  def pop
    @store.pop
  end

  def peek
    @store.last
  end

  def empty?
    @store.empty?
  end

end

Queue实现
class Queue

  def initialize
    @store = []
  end

  def enqueue(x)
    @store << x
  end

  def dequeue
    @store.shift
  end

  def peek
    @store.first
  end

  def length
    @store.length
  end

  def empty?
    @store.empty?
  end

end

Tree

宽度优先插入和遍历的二插树实现
class Tree

  attr_accessor :left
  attr_accessor :right
  attr_accessor :data

  def initialize(x=nil)
    @left = nil
    @right = nil
    @data = x
  end

  def insert(x)
    list = []
    if @data == nil
      @data = x
    elsif @left == nil
      @left = Tree.new(x)
    elsif @right == nil
      @right = Tree.new(x)
    else
      list << @left
      list << @right
      loop do
        node = list.shift
        if node.left == nil
          node.insert(x)
          break
        else
          list << node.left
        end
        if node.right == nil
          node.insert(x)
          break
        else
          list << node.right
        end
      end
    end
  end

  def traverse()
    list = []
    yield @data
    list << @left if @left != nil
    list << @right if @right != nil
    loop do
      break if list.empty?
      node = list.shift
      yield node.data
      list << node.left if node.left != nil
      list << node.right if node.right != nil
    end
  end
end

可搜索的二叉树实现
class Tree

  attr_accessor :left
  attr_accessor :right
  attr_accessor :data

  def initialize(x=nil)
    @left = nil
    @right = nil
    @data = x
  end

  def insert(x)
    if @data == nil
      @data = x
    elsif x <= @data
      if left == nil
        @left = Tree.new x
      else
        @left.insert x
      end
    else
      if @right == nil
        @right = Tree.new x
      else
        @right.insert x
      end
    end
  end

  def inorder()
    @left.inorder {|y| yield y} if @left != nil
    yield @data
    @right.preorder {|y| yield y} if @right != nil
  end

  def preorder()
    yield @data
    @left.postorder {|y| yield y} if @left != nil
    @right.postorder {|y| yield y} if @right != nil
  end

  def postorder()
    @left.postorder {|y| yield y} if @left != nil
    @right.postorder {|y| yield y} if @right != nil
    yield @data
  end

end

Graph

class LowerMatrix < TriMatrix

  def initialize
    @store = ZArray.new
  end

end

class Graph

  def initialize(*edges)
    @store = LowerMatirx.new
    @max = 0
    for e in edges
      e[0], e[1] = e[1], e[0] if e[1] > e[0]
      @store[e[0], e[1]] = 1
      @max = [@max, e[0], e[1]].max
    end
  end

  def [](x,y)
    if x > y
      @store[x,y]
    elsif x < y
      @store[y,x]
    else
      0
    end
  end

  def []=(x,y,v)
    if x > y
      @store[x,y] = v
    elsif x < y
      @store[y,x] = v
    else
      0
    end
  end

  def edge? x,y
    x,y = y,x if x < y
    @store[x,y] == 1
  end

  def add x,y
    @store[x,y] = 1
  end

  def remove x,y
    x,y = y,x if x < y
    @store[x,y] = 0
    if (degree @max) == 0
      @max -= 1
    end
  end

  def vmax
    @max
  end

  def degree x
    sum = 0
    0.upto @max do |i|
      sum += self[x,i]
    end
    sum
  end

  def each_vertex
    (0..@max).each {|v| yield v}
  end

  def each_edge
    for v0 in 0..@max
      for v1 in 0..v0-1
        yield v0,v1 if self[v0,v1] == 1
      end
    end
  end

end

另外RAA和Rubyforge上有RubyGraph,RGraph和GraphR等Ruby的Graph Tools
分享到:
评论
3 楼 jim.jin 2008-08-08  
请问怎么安装 TriMatrix 库,或哪里可以下载?
2 楼 hideto 2008-01-24  
确实实现了Queue,可能我看的书old了
1 楼 linkerlin 2008-01-24  
thread库不是有一个线程安全的Queue吗?

相关推荐

Global site tag (gtag.js) - Google Analytics