并查集 Python 版本

今天忽然诗意大发,“咳咳”,真的就是诗意大发。

 

数据结构也是也是比较单一的,elem, prev, ind。真正实施的时候,只需要前两个维度,为了让正确率更高,调试代码的速度变快,采用一些自己能掌握的指标。

 

并查集是使用树结构来解决,并集和查找元素的问题。在数据结构设计上,是 enough 的,因此,那种天真地想要从上至下输出或者遍历并查集是比较可笑的。这个问题很简单,如果你希望从上至下来遍历的话呢,你只需要使用 BST 二叉查找树,就能解决问题。记住,并查集,一定是,先确定元素,再自底向上搜索的。

 

预备数据集:

# 线性数组表示法
vec_elem=['A','B','C','D','E','F','G','H','I','J','K','L','M']
vec_prev=[-1,0,-1,-1,1,1,2,3,3,3,4,4,7]
vec_tag=0
vec_grp=-1

disjoint_set=pd.DataFrame([])
disjoint_set['elem']=vec_elem
disjoint_set['prev']=vec_prev

disjoint_set['ind']=disjoint_set.index          
disjoint_set

from IPython.display import Image
Image("https://userspace1.oss-cn-beijing.aliyuncs.com/article/bingchaji_6.png",width=600,height=500)

# REMARK:主要考察有几个 ELEMENT

并查集案例

 

数据集运行结果:

 

 

函数介绍:

1.为了用户更加快速地理解函数,我们写个说明书。主要的函数,是并集合,union_set() 以及查找元素 find_elem(),后者只需要一段代码即可解决。

2.其次,是确定辅助函数,例如,并集的时候,规定:矮的并入高的。因此,确定函数 swap_val(), 如果两棵树的高度反了话,再换回来。

3.确定函数 计算深度 cal_depth() 返回集合中所有的树,及对应深度。

4.计算函数子树是否已经被记录 is_existed() ,是的话返回该树坐标,否则 append

# --- FIND ---

def find_elem(vec_in, elem_in):
    # --- Input: 元素所在集合,元素本身
    # --- Ouput: 根所在 ind, 根所在的 elem, 根所在的 深度
    for i in range(len(vec_in)):
        if(vec_in['elem'][i] == elem_in):
            tmp_elem_ind = i
            break
    cnt_iter=0
    ind_prev=tmp_elem_ind

    while( int(vec_in['prev'][ind_prev])>-1 and cnt_iter< 50 ):
        ind_prev=vec_in['prev'][ind_prev]
        cnt_iter=cnt_iter+1
        
    root_ind = ind_prev
    elem_out = vec_in['elem'][root_ind]
    depth_out = cnt_iter+1
    return root_ind, elem_out, depth_out
        

    
# --- UNION ---
def swap_val(a, b):
    if(a>b):
        tmp=a; a=b; b=tmp
    return a, b


def union_set(vec_in, root_1, root_2):
    if(root_1==root_2):
        return;
    else:
          # -- 保证 root_2 比较矮
        vec_ind, vec_depth, vec_cnt = cal_depth(vec_in)
        ind_1=is_existed(vec_ind, root_1)
        ind_2=is_existed(vec_ind, root_2)
    
          # -- 互换
        if (vec_depth[ind_1] < vec_depth[ind_2]):
            root_1, root_2 = swap_val(root_1, root_2) 
        
          # --- root_2 必然是比较矮的树
        vec_in['prev'][vec_in.ind==root_2]=root_1;
        return

    
def is_existed(vec_in, elem_in):
    # input list
    ind_existed=-1
    for i in range(len(vec_in)):
        if(elem_in == vec_in[i]):
            ind_existed=i
            break
    return ind_existed
    
    
def cal_depth(vec_in):
    vec_root_ind=[]
    vec_root_depth=[]
    vec_root_cnt=[]
    
    for i in range(len(vec_in)):
        tmp_elem = vec_in['elem'][i]
        tmp_ind, tmp_root_elem, tmp_depth = find_elem(vec_in, tmp_elem)
        ind_root=is_existed(vec_root_ind, tmp_ind)
        
        if(ind_root>-1):
            vec_root_cnt[ind_root] = vec_root_cnt[ind_root]+1
            if(vec_root_depth[ind_root] < tmp_depth ):
                vec_root_depth[ind_root]=tmp_depth      
        else:
            vec_root_ind.append(tmp_ind)
            vec_root_depth.append(tmp_depth)
            vec_root_cnt.append(1)
    
    #print("Index of roots in forest: ", vec_root_ind)
    #print("Depth of trees: ", vec_root_depth)
    #print("#Node of trees: ", vec_root_cnt )
    return vec_root_ind, vec_root_depth, vec_root_cnt

 

查找部分:

传入:集合,需要被查找的元素”I“

传出:根节点 ind, 根节点元素,元素到根的深度

root_1, elem_1, depth_1 = find_elem(disjoint_set,"I")
print("Root/Elem of Input is: ", root_1, "/", elem_1, "/", depth_1)

 

运行结果:

 

并集合,使用到查找:

1.传入元素,返回根ind

2.将根 ind 传入 union_set(集合,根ind_1, 根ind_2)

# -- 左1 + 左2
e_1="B"
e_2="G"
r1,_,_ = find_elem(disjoint_set, e_1)
r2,_,_ = find_elem(disjoint_set, e_2)
print("The roots of '", e_1, "' & '", e_2, "' are: ", r1,r2)


 # ---- Union  
union_set( disjoint_set, r1, r2 )
print("Union 2 Trees and being shown as follows: \n")
disjoint_set

 

运行结果:

1.数据集输出 

2.图片展示

 

再并入一棵子树:

# -- 左1 + 左2
e_3="E"
e_4="M"
r3,_,_ = find_elem(disjoint_set, e_3)
r4,_,_ = find_elem(disjoint_set, e_4)
print("The roots of '", e_3, "' & '", e_4, "' are: ", r3, r4)


union_set( disjoint_set, r3, r4 )
print("Union 2 Trees and being shown as follows: \n")
disjoint_set

 

1.数据结构结果

2.图示

 

欢迎伙伴们关注 ShoelessCai.com 。

posted on 2023-10-21 21:43  Mira_2019  阅读(73)  评论(0编辑  收藏  举报