诗歌rails之 高级数据结构
关键字: set stack queue tree graph
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
初始化
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
莫愁前路无知己,天下无人不识君。