zoukankan      html  css  js  c++  java
  • 并查集数据结构的几种实现

    第一种实现

    每一个节点都只是指向根节点

    find是 常数时间复杂度的, union是 线性时间复杂度的。

    class quickFind {
      int[] a;
      int count;
    
      void init (int N) {
        a = new int[N];
        for (int i = 0; i < N; i++) {
          a[i] = i;
        }
        count = N;
      }
      boolean connected(int p , int q) {
        return find(p) == find(q);
      }
      int find (int p) {
        return a[p];
      }
      void union(int p , int q) {
        int proot = find(p);
        int qroot = find(q);
        if (proot == qroot) {
          return;
        }
        for (int i = 0; i < a.length; i++) {
          if (a[i] == proot) {
            a[i] = qroot;
          }
        }
        count--;
      }
    }

    第二种实现

    每一个节点指向一个和自己在相同集合中的节点

    find操作是树的高度时间复杂度,union操作也是 树的高度时间复杂度

    class quickUnion {
      int[] a;
      int count;
    
      void init(int N) {
        a = new int[N];
        for (int i = 0; i < N; i++) {
          a[i] = i;
        }
        count = N;
      }
    
      void find(p) {
        while (p != a[p]) p = a[p];
        return p;
      }
    
      void union(int p, int q) {
        int proot = find(p);
        int qroot = find(q);
        if (proot == qroot) {
          return;
        }
        a[proot] = qroot;
        count--;
      }
    
      void connected(int p, int q) {
        return find(p) == find(q);
      }
    }

    第三种实现其实是第二种实现的改良版本

    因为第二种实现,当树的高度比较大,趋于链表的时候,时间复杂度会比较高,应该尽量减小树的高度

    find时间复杂度logn,union时间复杂度logn

    class quickUnion2 {
      int[] a;
      int count;
      int[] size;
    
      void init(int N) {
        a = new int[N];
        size = new int[N];
        for (int i = 0; i < N; i++) {
          a[i] = i;
          size[i] = 1;
        }
        count = N;
      }
    
      void find(p) {
        while (p != a[p]) p = a[p];
        return p;
      }
    
      void union(int p, int q) {
        int proot = find(p);
        int qroot = find(q);
        if (proot == qroot) {
          return;
        }
        if (size[proot] < size[qroot]) {
          a[proot] = qroot;
          size[qroot] += size[proot];
        } else {
          a[qroot] = proot;
          size[proot] += size[qroot];
        }
        count--;
      }
      void connected(int p, int q) {
        return find(p) == find(q);
      }
    }

    使用场景,比如 岛屿个数 问题,除了用深度优先搜索之外,还可以用 并查集数据结构来做。

  • 相关阅读:
    PHP 超级全局变量
    PHP 魔术变量
    PHP 变量
    Thinkphp 模板中常用的系统变量总结
    PHP $GLOBALS超全局变量分析
    php使用curl的post提交数据和get获取网页数据的方法总结
    php获取客户端真实ip地址的三种方法
    Jquery 【on事件】
    ptyhon【递归练习】
    C#中的线程
  • 原文地址:https://www.cnblogs.com/tobemaster/p/10206772.html
Copyright © 2011-2022 走看看