算法实践--不相交集合(Disjoint Sets)

什么是不相交集合(Disjoint Sets)

是这样的一组set,任何元素最多只能在一个set中

 

至少支持查找Find和合并Union操作

 

实现方式(基于树)

  • 每个set都是一棵树
  • 每棵树都由树的根节点识别

 

 

  • 合并操作只需要修改根节点的指针

 

  • 合并的复杂度是O(1)
  • 查找的复杂度是O(depth) ,树的深度
  • 可以方便地通过指针来实现
struct item {
  char data;
  Item* parent;
}
  • 但是如果数据结构中没有指针,需要自己在外面再套一层结果,比较麻烦
  • 还有另一种方法是通过hash表来实现,不需要指针

 

C++代码实现

class Disjoint_set {
  unordered_map<char, char> PARENT;
  unordered_map<char, int> RANK;  //记录深度
  public:
  Disjoint_set() {
    char universe[] ] {'a', 'b', 'c', 'd', 'e'};
    for (char x : universe) {
      PARENT[x] = x;
      RANK[x] = 0;
    }
    PARENT['d'] = 'b';  //d指向b,b和d在同一个集合
    RANK['b']++;
  }

  char Find(char item) {
    if (PARENT[item] == item)
      return item;
    else
      Find(PARENT[item]);
  }

  // 查找的复杂度取决于树的深度,优化合并操作
  void Union(char set_1, char set_2) {  //谁深指向谁
    if (RANK[set_1] > RANK[set_2])
      PARENT[set_2] = set_1;
    else if (RANK[set_2] > RANK[set_1])
      PARENT[set_1] = set_2;
    else {
      PARENT[set_1] = set_2;
      RANK[set_2]++;
    }
  }
};

int main() {
  Disjoint_set ds;
  ds.Find('c'); //返回c
  ds.union('c', 'a'); //c指向a
  ds.Find('c');|//返回a
  ds.union('a', 'b');|//a指向b
}

 

转载于:https://www.cnblogs.com/logchen/p/10269817.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值