github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/graph/path/disjoint.go (about)

     1  // Copyright ©2014 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package path
     6  
     7  // djSet implements a disjoint set finder using the union-find algorithm.
     8  type djSet map[int64]*dsNode
     9  
    10  // add adds e to the collection of sets held by the disjoint set.
    11  func (s djSet) add(e int64) {
    12  	if _, ok := s[e]; ok {
    13  		return
    14  	}
    15  	s[e] = &dsNode{}
    16  }
    17  
    18  // union joins two sets a and b within the collection of sets held by
    19  // the disjoint set.
    20  func (djSet) union(a, b *dsNode) {
    21  	ra := find(a)
    22  	rb := find(b)
    23  	if ra == rb {
    24  		return
    25  	}
    26  	if ra.rank < rb.rank {
    27  		ra.parent = rb
    28  		return
    29  	}
    30  	rb.parent = ra
    31  	if ra.rank == rb.rank {
    32  		ra.rank++
    33  	}
    34  }
    35  
    36  // find returns the root of the set containing e.
    37  func (s djSet) find(e int64) *dsNode {
    38  	n, ok := s[e]
    39  	if !ok {
    40  		return nil
    41  	}
    42  	return find(n)
    43  }
    44  
    45  // find returns the root of the set containing the set node, n.
    46  func find(n *dsNode) *dsNode {
    47  	for ; n.parent != nil; n = n.parent {
    48  	}
    49  	return n
    50  }
    51  
    52  // dsNode is a disjoint set element.
    53  type dsNode struct {
    54  	parent *dsNode
    55  	rank   int
    56  }