Class: UnionFind::UnionFind
- Inherits:
-
Object
- Object
- UnionFind::UnionFind
- Defined in:
- lib/union_find.rb
Overview
Instance Method Summary collapse
-
#connected?(component_1, component_2) ⇒ Boolean
Do two components share the same root?.
-
#count_isolated_components ⇒ Interger
Returns the number of isolated components.
-
#find_root(component) ⇒ Component
Returns the root of a component.
-
#initialize(components) ⇒ UnionFind
constructor
Initializes an empty union-find data structure with n isolated components 0 through n-1.
-
#union(component_1, component_2) ⇒ Component, NilClass
Connect root of component 1 with root of component 2 by attaching smaller subtree root node with larger tree.
Constructor Details
#initialize(components) ⇒ UnionFind
Initializes an empty union-find data structure with n isolated components 0 through n-1.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/union_find.rb', line 31 def initialize(components) raise ArgumentError, 'input is not an Array' unless components.class == Array components = components.uniq # remove duplicates @number_of_isolated_components = components.length raise ArgumentError, 'number of components is < 1' if @number_of_isolated_components < 1 @parent = {} # parent of i @tree_size = {} # size of tree rooted at i (cannot be more than 31) components.each do |component| @parent[component] = component @tree_size[component] = 1 end end |
Instance Method Details
#connected?(component_1, component_2) ⇒ Boolean
Do two components share the same root?
101 102 103 |
# File 'lib/union_find.rb', line 101 def connected?(component_1, component_2) find_root(component_1) == find_root(component_2) end |
#count_isolated_components ⇒ Interger
Returns the number of isolated components.
49 50 51 |
# File 'lib/union_find.rb', line 49 def count_isolated_components @number_of_isolated_components end |
#find_root(component) ⇒ Component
Returns the root of a component.
57 58 59 60 61 62 63 64 65 66 |
# File 'lib/union_find.rb', line 57 def find_root(component) raise IndexError, 'component does not exist' unless @parent[component] while component != @parent[component] # stop at the top node where component id == parent id @parent[component] = @parent[@parent[component]] # path compression by halving component = @parent[component] end return component end |
#union(component_1, component_2) ⇒ Component, NilClass
Connect root of component 1 with root of component 2 by attaching smaller subtree root node with larger tree. If both trees have the same size, the root of the second component becomes a child of the root of the first component.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/union_find.rb', line 75 def union(component_1, component_2) root_component_1 = find_root(component_1) root_component_2 = find_root(component_2) return nil if root_component_1 == root_component_2 # make smaller root point to larger one if @tree_size[root_component_1] < @tree_size[root_component_2] @parent[root_component_1] = root_component_2 root = root_component_2 @tree_size[root_component_2] += @tree_size[root_component_1] else @parent[root_component_2] = root_component_1 root = root_component_1 @tree_size[root_component_1] += @tree_size[root_component_2] end @number_of_isolated_components -= 1 root end |