演算法之並查集 C語言實現3
阿新 • • 發佈:2019-01-07
標頭檔案 UnionFind3.h
#ifndef UNIONFIND3_H_INCLUDED #define UNIONFIND3_H_INCLUDED #include "stdlib.h" #include "ASSERT.h" typedef struct{ int* parent; int* rank;//rank[i]表示以i為根的集合中樹的層數 int count; }Union; void unionFind3Init(Union *un,int n); void freeUnion3(Union *un); int unionFind3(Union *un,int p); int isConnected3(Union *un,int p,int q); void unionElements3(Union *un,int p,int q); #endif // UNIONFIND_H_INCLUDED
c程式碼 UnionFind3.c
#include "UnionFind3.h" /********************************************* *函式名:並查集的初始化 *********************************************/ void unionFind3Init(Union *un,int n){ int i; un->count = n; un->parent = (int*)malloc(n*sizeof(int)); un->rank = (int*)malloc(n*sizeof(int)); for(i=0;i<n;i++){ un->parent[i] = i; un->rank[i] = 1; } } /********************************************* *函式名:並查集將空間釋放 *********************************************/ void freeUnion3(Union *un){ free(un->parent); free(un->rank); } /********************************************* *函式名:返回並查集中p的ID(採用路徑壓縮) *********************************************/ int unionFind3(Union *un,int p){ assert(p >= 0 && p< un->count); // while(p != un->parent[p]){ // un->parent[p] = un->parent[un->parent[p]]; //路徑壓縮 // p = un->parent[p]; // } // return p; if(p != un->parent[p]){ //使用遞迴的方法進行路徑壓縮 un->parent[p] = unionFind3(un,un->parent[p]); } return un->parent[p]; } /********************************************* *函式名:判斷並查集中p和q是否是一個集合 *********************************************/ int isConnected3(Union *un,int p,int q){ return unionFind3(un,p) == unionFind3(un,q) ; } /********************************************* *函式名:並查集的合併 *********************************************/ void unionElements3(Union *un,int p,int q){ int pRoot = unionFind3(un,p); int qRoot = unionFind3(un,q); if(pRoot == qRoot){ return ; } else if(un->rank[pRoot] < un->rank[qRoot]){ un->parent[pRoot] = qRoot; } else if(un->rank[pRoot] > un->rank[qRoot]){ un->parent[qRoot] = pRoot; } else{ un->parent[pRoot] = qRoot; un->rank[qRoot] += 1; } }