當前位置: 首頁>>數據結構>>正文


並查集的數組實現(C++) (原創)

摘要:本文簡要介紹了並查集的基本原理,並且給出了簡單易於理解的數組實現。本文給出的實現方法

使用數組而不是通用的樹結構,是為了方便對並查集的理解,其合並的時間複雜度是O(N),不適合高效

的應用。高效的並查集實現請參見博文《並查集的樹形實現》。

關鍵字:並查集,Union,Find,Set,UnionFind

並查集是一個通用的數據結構,經典的應用有最小生成樹的Kruskal算法。該結構可用於判斷元素所

在的集合以及合並不相交的集合。一般並查集有三個主要的方法:

一是初始化,UnionFindSet_Init(int n),用於初始化並查集。

二是查找一個元素所在的集合,UnionFindSet_Find(int x),查找元素X。

三是合並兩個元素所在的集合,UnionFindSet_Merge(int x, int y)。

本文給出的實現中使用一個數組UnionFindSet[N]保存所有可能出現的元素,UnionSetFind[i]表示元素

i所在的集合編號,同一集合中的元素集合編號相同且唯一。首先將所有元素視為孤立的集合,為每個元素

設置一個集合編號;當合並某兩個元素所在的集合A和B時,將一個集合中的所有元素的集合編號設置為另

一個集合的元素編號;當查找某個元素所在的集合編號是,返回UnionSetFind[i]即可。

以上思想的C++實現如下:


/*
 *並查集的數組實現
 */

//實現方法一,數組
//INIT時間複雜度,O(N)
//FIND時間複雜度,O(1)
//Merge時間複雜度,O(N)

#include <iostream>

using namespace std;

#define N 1000

int UnionFindSet[N];

void uf_init(int n); //初始化並查集,每個點都是一個集合
int uf_find(int x); //在並查集中查找一個元素,返回集合編號
void uf_merge(int x, int y, int n); //合並兩個元素所在的集合

int main(int argc, char* *argv)
{
      int n = 20;
      uf_init(n);
      uf_merge(1, 3, n);
      uf_merge(2, 3, n);
      uf_merge(4, 5, n);
      uf_merge(10, 13, n);
      uf_merge(4, 13, n);
      if(uf_find(1) == uf_find(3))
      {
            cout<<"success1"<<endl;
      }
      if(uf_find(5) == uf_find(10))
      {
            cout<<"success2"<<endl;
      }
      if(uf_find(1) != uf_find(4))
      {
            cout<<"success3"<<endl;
      }
      system("pause");
      return 0;
}

void uf_init(int n)
{
      //時間複雜度O(N)
      for(int i = 0; i < n; ++i)
            UnionFindSet[i] = i;
}

int uf_find(int x) //ensure x>=0 && x < n
{
      //時間複雜度O(1)
      return UnionFindSet[x];
}

void uf_merge(int x, int y, int n)//ensure x,y>=0 && x,y < n
{
      //時間複雜度O(N)
      int set_id1 = UnionFindSet[x];
      int set_id2 = UnionFindSet[y];
      for(int i = 0; i < n; ++i)
            if(UnionFindSet[i] == set_id1)
                  UnionFindSet[i] = set_id2;
}
本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/137.html,未經允許,請勿轉載。