第二十一章 用于不相交集合的数据结构

来源:互联网 发布:freeswitch java 编辑:程序博客网 时间:2024/06/04 19:35

21.1不相交集合的操作

def:不相交集合数据结构维护了一个不相交动态集的集合S={S1, S2,...,Sk}。我们用一个代表来表示每个集合,他是这个集合的某个成员。设x表示一个动态集Sx的每个元素,我们希望支持以下三个操作:


使用不相交集合的数据结构来确定无向图的连通分量过程如下:


21.2 不相交集合的链表表示

用链表来表示集合实现如下:

class Set():    def __init__(self):        self.head = None        self.tail = None        self.size = 0class Node():    def __init__(self, x):        self.set = None        self.value = x        self.next = Nonedef MAKE_SET(x):    node = Node(x)    st = Set()    st.head = node    st.tail = node    st.size = 1    node.set = st    return nodedef FIND_SET(x):    return x.set.headdef UNION(x, y):    ySet = y.set    xSet = x.set    xTail = xSet.tail    yHead = ySet.head    ySet.head = None    ySet.tail = None    xTail.next = yHead    yHead.set = xSet    while yHead.next != None:        yHead = yHead.next        yHead.set = xSet    xSet.tail = yHead    return xSet.headdef WEIGHT_UNION(x, y):    xWeight = x.set.size    yWeight = y.set.size    if xWeight > yWeight:        ret = UNION(x, y)        ret.set.size = xWeight + yWeight        return ret    else:        ret = UNION(y, x)        ret.set.size = xWeight + yWeight        return retdef PRINT(x):    head = x.set.head    while head != None:        print(head.value)        head = head.nextif __name__ == "__main__":    setf = MAKE_SET('f')    setg = MAKE_SET('g')    setd = MAKE_SET('d')    set1 = WEIGHT_UNION(setf, setg)    set1 = WEIGHT_UNION(set1, setd)    PRINT(set1)    print("=================")    setc = MAKE_SET('c')    seth = MAKE_SET('h')    sete = MAKE_SET('e')    setb = MAKE_SET('b')    set2 = WEIGHT_UNION(setc, seth)    set2 = WEIGHT_UNION(set2, sete)    set2 = WEIGHT_UNION(set2, setb)    PRINT(set2)    print("=================")    set3 = WEIGHT_UNION(set1, set2)    PRINT(set3)    print(setf.set.size)

以上过程示意图如下:

也可以采用加权的方式来合并提高合并效率:

21.3 不相交集合森林
不相交集合森林是不相交集合的更快实现:

class Node():    def __init__(self, x):        self.value = x        self.p = self        self.rank = 0def MAKE_SET(x):    x.p = x    x.rank = 0def UNION(x, y):    LINK(FIND_SET(x), FIND_SET(y))def LINK(x, y):    if x.rank > y.rank:        y.p = x    else:        x.p = y        if x.rank == y.rank:            y.rank = y.rank + 1def FIND_SET(x):    if x != x.p:        x.p = FIND_SET(x.p)    return x.pdef PRINT(x):    print(x.value)    if x.p != x:        PRINT(x.p)        if __name__ == "__main__":    array = []    array.append(Node('a'))    array.append(Node('b'))    array.append(Node('c'))    array.append(Node('d'))    array.append(Node('e'))    array.append(Node('f'))    for i in range(0, len(array)):        array[i].rank = i+1    for i in range(0, len(array)-1):        UNION(array[i], array[i+1])    PRINT(array[0])    print("-----------------")    FIND_SET(array[0])    for i in range(0, len(array)):        PRINT(array[i])
实现如下图所示结构:

并采用按秩合并和路径压缩两种启发式策略:



21.4 带路径压缩的按秩合并的分析






0 0
原创粉丝点击