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

本文介绍了Ruby中的Set、Stack、Queue、Tree和Graph等基本数据结构的实现与使用方法,并提供了详细的代码示例。
[b]Set[/b]

初始化
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}>}>

[b]Stack&Queue[/b]

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

[b]Tree[/b]

宽度优先插入和遍历的二插树实现
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

[b]Graph[/b]

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值