Non-intersecting set ADT

Source: Internet
Author: User

The data structure of the non-intersecting set keeps a group of non-Intersecting dynamic sets S = {S1, S2 ,..., SK}, each set is identified by a representative, representing a member of the set.

If x represents an object, the following operations are supported for non-intersecting sets:

MAKE-SET (x): Creates a new SET with the unique member x. Because each set does not want to be handed in, x does not appear in other sets.

UNION (x, y): combines a set containing x and y into a new set.

FIND-SET (x): returns the SET containing x.

1. array representation of non-intersecting sets

Save the name of the set where each element is located in an array. In this way, the Find operation is a simple O (1) Search. To perform the Union (x, y) operation, assume that x is in equivalence class I and y is in Equivalence Class j,

Scan the entire array and change all I to j. The Union operation of a continuous N-1 takes a certain amount of time (N2. This field is unacceptable if there are many Union operations.

2. List representation of non-intersecting sets

Each set is represented by a linked list. The first object of the linked list is represented by its collection. Each object in the linked list contains a set member and a pointer to the next object,

And pointer to the Representative. Each linked list contains head and tail pointers. head points to the linked list, and tail points to the last object in the linked list.

 

Simple implementation of Union: Concatenates the linked list of x to the end of the linked list of y. For each object in the linked list where x was originally located, update its pointer to the Representative.

On average, each operation requires a period (N.

Weighted merge: Each table contains the length of the table, which always connects shorter tables to the end of the long table. In this way, m, MAKE-SET, UNION, and FIND-SET operations will take (m + nlgn) time.

class SetNode(object):    def __init__(self,key):        self.key=key        self.next=None        self.rep=Noneclass SetEntry(object):    def __init__(self):        self.head=None        self.tail=None        self.len=0class DisjSet(object):    def __init__(self,node):        self.setlist=[]    def make_set(self,node):        S=SetEntry()        S.head=node        S.tail=node        S.len=1        node.rep=node        self.setlist.append(S)    def find(self,node):        return node.rep    def union(self,node_x,node_y):        rep_x=node_x.rep        rep_y=node_y.rep        if rep_x!=rep_y:            for s in self.setlist:                if s.head==rep_x:                    set_x=s                elif s.head==rep_y:                    set_y=s            if set_x.len>=set_y.len:                set_x.tail.next=rep_y                node=rep_y                while node is not None:                    node.rep=rep_x                    node=node.next                set_x.tail=set_y.tail                set_x.len=set_x.len+set_y.len                self.setlist.remove(set_y)                return rep_x            else:                set_y.tail.next=rep_x                node=rep_x                while node is not None:                    node.rep=rep_y                    node=node.next                set_y.tail=set_x.tail                set_y.len+=set_x.len                self.setlist.remove(set_x)                return rep_y
3. Non-Intersecting collection forest

A tree is used to represent a set. The root of the tree is used to represent the set. Each node in the tree contains element data and a pointer to the parent node. The pointer to the root node is null.

You can use arrays to represent the tree non-explicitly: each Member T [I] in the array represents the parent node of element I. If I is the root, take p [I] as 0 or-1.

If Union operations are performed randomly, the tree may become a degraded tree. There are several ways to avoid this situation.

3.1 smart merge algorithm

It always makes smaller trees a child tree of larger trees. Another method is to calculate the sum by height.

In this way, the depth of any node will not exceed logN, the running time of the Find operation is O (logN), and the O (MlogN) is consumed for M consecutive operations ).

When implemented, let each element of the array contain the negative value of its tree size.

class DisjSet(object):    def __init__(self,size):        self.list=[-1]*size    def find(self,x):        if self.list[x]<0:            return x        else:            return self.find(self.list[x])    def union(self,x,y):        set_x=self.find(x)        set_y=self.find(y)        if set_x!=set_y:            if self.list[set_x]>self.list[set_y]:                self.list[set_y]+=self.list[set_x]                self.list[set_x]=set_y                return set_y            else:                self.list[set_x]+=self.list[set_y]                self.list[set_y]=set_x                return set_x

3.2 path compression

Path compression is performed during a Find (X) operation. Each node from X to the root path changes its parent node to the root node.

Path compression is fully compatible with size-based computation, but not fully compatible with height-based computation. When the path is compressed, the height of each tree changes. You can estimate the storage height of each tree and use rank to represent it.

class DisjSet_with_rank(object):    def __init__(self,size):        self.list=[-1]*size    def find(self,x):        if self.list[x]<0:            return x        else:            self.list[x]=self.find(self.list[x])            return self.list[x]    def union(self,x,y):        set_x=self.find(x)        set_y=self.find(y)        if set_x!=set_y:            if self.list[set_x]<self.list[set_y]:                self.list[set_y]=set_x            else:                if self.list[set_x]==self.list[set_y]:                    self.list[set_y]-=1                self.list[set_x]=set_y

Explicit Representation of path compression

class SetNode(object):    def __init__(self,key):        self.parent=None        self.key=key        self.rank=1def find(node):    if node.parent is None:        return node    else:        node.parent=find(node.parent)        return node.parentdef union(x,y):    x=find(x)    y=find(y)    if x!=y:        if x.rank<=y.rank:            if x.rank==y.rank:                y.rank+=1            x.parent=y            return y        else:            y.parent=x            return x        

  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.