QuickUnion.h
#pragma once
#include <iostream>
using namespace std;
typedef int elem;
class QuickUnion {
private:
elem* nums;
int* size;
int len;
int* parentID;
private:
int findIndex(elem e) const;
int findRootIndex(elem e) const;
public:
QuickUnion(elem* nums, int len);
~QuickUnion();
void unionNum(elem a, elem b);
bool isSam(elem a, elem b);
};
QuickUnion.cpp
#include "QuickUnion.h"
int QuickUnion::findIndex(elem e) const {
for (int i = 0; i < len; i++) {
if (nums[i] == e) {
return i;
}
}
return -1;
}
int QuickUnion::findRootIndex(elem e) const {
int eIndex = findIndex(e);
if (eIndex != -1) {
while (parentID[eIndex] != eIndex) {
eIndex = parentID[eIndex];
}
return eIndex;
}
return -1;
}
QuickUnion::QuickUnion(elem* nums, int len){
if (len < 0) {
return;
}
this->len = len;
this->nums = new elem[len];
this->size = new int[len];
this->parentID = new int[len];
for (int i = 0; i < len; i++) {
this->nums[i] = nums[i];
this->size[i] = 1;
this->parentID[i] = i;
}
}
QuickUnion::~QuickUnion(){
delete nums;
delete size;
delete parentID;
}
void QuickUnion::unionNum(elem a, elem b) {
//int aIndex = findIndex(a);
//int bIndex = findIndex(b);
int aRoot = findRootIndex(a);
int bRoot = findRootIndex(b);
if (aRoot == bRoot) return;
if (size[aRoot] >= size[bRoot]) {
parentID[bRoot] = aRoot;
size[aRoot] += size[bRoot];
}
else {
parentID[aRoot] = bRoot;
size[bRoot] += size[aRoot];
}
}
bool QuickUnion::isSam(elem a, elem b){
int aRoot = findRootIndex(a);
int bRoot = findRootIndex(b);
if (aRoot == -1 || bRoot == -1 || aRoot!=bRoot) {
return false;
}
return true;
}
main.cpp
#include "AVLTree.h"
#include "QuickUnion.h"
void test02() {
int nums[] = {0,1,2,3,4,5,6,7,8};
QuickUnion QUset(nums, sizeof(nums) / sizeof(nums[0]));
QUset.unionNum(3, 4);
QUset.unionNum(8, 0);
QUset.unionNum(2, 3);
QUset.unionNum(5, 6);
if (QUset.isSam(0, 2)) {
printf("yes\n");
}
else {
printf("no\n");
}
if (QUset.isSam(2,4)) {
printf("yes\n");
}
else {
printf("no\n");
}
QUset.unionNum(5, 1);
QUset.unionNum(7, 3);
QUset.unionNum(1, 6);
QUset.unionNum(4, 8);
if (QUset.isSam(0, 2)) {
printf("yes\n");
}
else {
printf("no\n");
}
if (QUset.isSam(2, 4)) {
printf("yes\n");
}
else {
printf("no\n");
}
}
int main() {
test02();
return 0;
}
以上代码不包括路径压缩,我们可以采用栈结构,进行路径压缩,尽可能将结点指向root结点,用于减少树的高度,提高查找效率。代码如下(注意要包含stack头文件):
int QuickUnion::findRootIndex(elem e) const {
int eIndex = findIndex(e);
if (eIndex != -1) {
stack<int> st; //用于路径压缩
while (parentID[eIndex] != eIndex) {
st.push(eIndex);
eIndex = parentID[eIndex];
}
while (!st.empty()) {
int Index = st.top();
st.pop();
parentID[Index] = eIndex;
}
return eIndex;
}
return -1;
}

被折叠的 条评论
为什么被折叠?



