zoukankan      html  css  js  c++  java
  • 算法实践--不相交集合(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
    }
  • 相关阅读:
    顺序容器添加,查询,删除元素
    使用fiddler对app做弱网测试
    工作总结
    软件测试面试题_3
    软件测试面试题_2
    软件测试面试题_1
    MySQL的下载及安装
    关于let以及var的区别
    关于获取各种浏览器可见窗口大小的一点点研究
    log4J指定类下面的日志分隔
  • 原文地址:https://www.cnblogs.com/logchen/p/10269817.html
Copyright © 2011-2022 走看看