Skip to content

Commit

Permalink
Add additional constructors for DisjointSets (#567)
Browse files Browse the repository at this point in the history
* Add additional constructors for DisjointSets

* Modify how DisjointSets constructor handles types and iterators

* Add empty test and delete outdated constructor
  • Loading branch information
c-p-murphy authored and oxinabox committed Jan 15, 2020
1 parent 06559b3 commit e862972
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/disjoint_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ length(s::IntDisjointSets) = length(s.parents)
num_groups(s::IntDisjointSets) = s.ngroups
Base.eltype(::Type{IntDisjointSets}) = Int


# find the root element of the subset that contains x
# path compression is implemented here
#
Expand Down Expand Up @@ -111,6 +110,7 @@ mutable struct DisjointSets{T}
revmap::Vector{T}
internal::IntDisjointSets

DisjointSets{T}() where T = new{T}(Dict{T,Int}(), Vector{T}(), IntDisjointSets(0))
function DisjointSets{T}(xs) where T # xs must be iterable
imap = Dict{T,Int}()
rmap = Vector{T}()
Expand All @@ -126,9 +126,21 @@ mutable struct DisjointSets{T}
end
end

DisjointSets() = DisjointSets{Any}()
DisjointSets(xs::T...) where T = DisjointSets{T}(xs)
DisjointSets{T}(xs::T...) where T = DisjointSets{T}(xs)
DisjointSets(xs) = _DisjointSets(xs, Base.IteratorEltype(xs))
_DisjointSets(xs, ::Base.HasEltype) = DisjointSets{eltype(xs)}(xs)
function _DisjointSets(xs, ::Base.EltypeUnknown)
T = Base.@default_eltype(xs)
(isconcretetype(T) || T === Union{}) || return grow_to!(DisjointSets{T}(), xs)
return DisjointSets{T}(xs)
end

length(s::DisjointSets) = length(s.internal)
num_groups(s::DisjointSets) = num_groups(s.internal)
Base.eltype(::Type{DisjointSets{T}}) where T = T
empty(s::DisjointSets{T}, ::Type{U}=T) where {T,U} = DisjointSets{U}()

"""
find_root{T}(s::DisjointSets{T}, x::T)
Expand Down
11 changes: 11 additions & 0 deletions test/test_disjoint_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,22 @@
# DisjointSets supports arbitrary indices
s = DisjointSets{Int}(1:10)

@testset "constructor" begin
@test DisjointSets() isa DisjointSets{Any}
@test DisjointSets{Int}(1:10) isa DisjointSets{Int}
@test DisjointSets{Float64}(1.0:10.0...) isa DisjointSets{Float64}
@test DisjointSets(collect(1:10)) isa DisjointSets{Int}
@test DisjointSets(collect(1.0:10.0)...) isa DisjointSets{Float64}
@test DisjointSets(x*im for x = 1:10) isa DisjointSets{Complex{Int}}
end

@testset "basic tests" begin
@test length(s) == 10
@test num_groups(s) == 10
@test eltype(s) == Int
@test eltype(typeof(s)) == Int
@test length(empty(s)) == num_groups(empty(s)) == 0
@test empty(s) isa DisjointSets{eltype(s)}

r = [find_root(s, i) for i in 1 : 10]
@test isequal(r, collect(1:10))
Expand Down

0 comments on commit e862972

Please sign in to comment.