用c++實現了乙個int型別的並查集,實現了三個版本,是逐個優化的乙個過程
// 第一版(採用一致id的形式,即p,q如果關聯,則p, q的id一定完全一致)
class unionfind_1e
}bool isconnected(int p, int q)
void unionelements(int p, int q)
for (int i = 0; i <= count; ++i) }}
private:
int find(int p)
private:
std::vectorid;
int count = 0;
};
// 第二版(採用parent的方式,即指向如果p,q關聯,則值需要保證p, q最終的祖先一致就行)
class unionfind_2e
}bool isconnected(int p, int q)
void unionelements(int p, int q)
// 效率高
parent[proot] = qroot;
}private:
int find(int p)
return p;
}private:
std::vectorparent;
int count;
};
第二版(層級優化)
// 第二版(按照層級優化,即union的時候,將層級小的一方掛載到層級高的一方)
class unionfind_2e_rank
rank.resize(count + 1, 1); // 初始每個的層級均為1
}bool isconnected(int p, int q)
void unionelements(int p, int q)
if (rank[proot] < rank[qroot]) else if (rank[proot] > rank[qroot]) else
}private:
int find(int p)
return p;
}private:
std::vectorparent;
int count;
std::vectorrank;
};
第二版(數量優化)
// 第二版(按照數量優化,即union的時候將數量少的一方掛載到數量多的一方)
class unionfind_2e_sz
sz.resize(count + 1, 1); // 初始每個的數量均為1
}bool isconnected(int p, int q)
void unionelements(int p, int q)
if (sz[proot] < sz[qroot]) else if (sz[proot] > sz[qroot]) else
}private:
int find(int p)
return p;
}private:
std::vectorparent;
int count;
std::vectorsz;
};
// 第三版(防止層級過高帶來的查詢效能,進行路徑壓縮優化)
class unionfind_3e
rank.resize(count + 1, 1); // 初始每個的層級均為1
}bool isconnected(int p, int q)
void unionelements(int p, int q)
if (rank[proot] < rank[qroot]) else if (rank[proot] > rank[qroot]) else
}private:
int find(int p)
return p;
}private:
std::vectorparent;
int count;
std::vectorrank;
};
void test()
並查集的實現及優化
並查集是一種用於在森林中判斷子圖數量及點的歸屬的資料結構,由於其特殊的路徑壓縮操作,使得這一過程可以異常地快。並查集主要由乙個pre陣列以及兩個函式組成 find函式和join函式。pre陣列表示每一節點的前驅,最終已完成的並查集,每乙個子圖的所有點只有乙個前驅 這也是其高效的原因 而初始化的並查集...
並查集的實現與優化
並查集的實現與優化 班上有 n 名學生。其中有些人是朋友,有些則不是。他們的友誼具有是傳遞性。如果已知 a 是 b 的朋友,b 是 c 的朋友,那麼我們可以認為 a 也是 c 的朋友。所謂的朋友圈,是指所有朋友的集合。給定乙個 n n 的矩陣 m,表示班級中學生之間的朋友關係。如果m i j 1,表...
帶權並查集 學習乙個
生活有點小煩,希望在寫 的時候能夠純粹一點。先作一點鋪墊 從以前的認識來看,並查集 union find sets 可以實現分類的目的。她提供兩種操作 1.find 查詢根節點 2.union 合併 兩個元素間的關係將兩個不同集合合併為乙個,保證了關係的傳遞性 值得注意的是並查集有兩個優化的方法 1...