Merge 不交集的并
我正在研究支持联合功能的不相交集 降低树木高度的技术: 我们总是将较小的树合并到较大的树上,也就是说,我们使较小树的根指向较大树的根 如果一棵树有更多的节点,它就比另一棵树大 每个节点都是一个带有字段的结构:元素的一些信息、指向父节点的指针“parent”和计数器“count”,仅当节点是根节点并且包含上行树中的节点数时才使用 以下算法合并两个上行树:Merge 不交集的并,merge,hashtable,union-find,Merge,Hashtable,Union Find,我正在研究支持联合功能的不相交集 降低树木高度的技术: 我们总是将较小的树合并到较大的树上,也就是说,我们使较小树的根指向较大树的根 如果一棵树有更多的节点,它就比另一棵树大 每个节点都是一个带有字段的结构:元素的一些信息、指向父节点的指针“parent”和计数器“count”,仅当节点是根节点并且包含上行树中的节点数时才使用 以下算法合并两个上行树: pointer UpTreeUnion(pointer S,T) { if (S == NULL OR P == NULL) return
pointer UpTreeUnion(pointer S,T) {
if (S == NULL OR P == NULL) return;
if (S->count >= T->count) {
S->count = S->count + T->count;
T->parent = S;
return S;
}
else {
T->count = T->count + S->count;
S->parent = T;
return T;
}
}
考虑使用并集实现不相交集,其中最多可以有k个不相交集。
该实现使用一个哈希表a[0..max-1],其中存储了基于方法有序双哈希的密钥。
设h1和h2分别是主散列函数和次散列函数。A包含上述所有树的节点的键,以及指向每个树的相应节点的指针。
我想写一个算法,将两个节点的键作为参数,合并节点所属的up树(节点可以属于任何up树,即使在相同的情况下,它也会显示适当的消息)。在合并时,我们应该应用路径压缩和高度缩减技术
你能告诉我怎么做吗
假设我们有这个数组:
开始时,节点将如下所示:
那么如果k1=100,k2=5,在应用算法之后,我们会得到这个吗
如果我们有k1=59,k2=5,我们将得到以下结果:
对吧??然后应用路径压缩,我们开始执行以下操作:
tmp=B
while (B->parent!=B)
parent=B->parent;
tmp->parent=B;
tmp=parent;
}
所以我们将有parent=F,tmp->parent=B,tmp=F
我们如何继续
然后k1=14,k2=59,我们得到:
首先,当您获取密钥时,需要在哈希表中找到它们。
哈希表包含以下项:
(键,指向节点的指针)
假设您要查找键
k
。您检查:A[h1(k)+0*h2(k)mod size(A)]
-如果它包含键k
,则读取指向节点的相应指针。如果存在
k
以外的内容,请选中:A[h1(k)+1*h2(k)模块大小(A)]
,A[h1(k)+2*h2(k)模块大小(A)]
,A[h1(k)+i*h2(k)模块大小(A)]
。。。直到找到键k
现在您有了指向2个节点的指针,您需要找到这些节点所属的树的根。要找到根,请沿着树向上走,直到到达根节点。您可以为它使用每个节点的parent
指针,并且可以假设root的parent
指针指向自身
现在您有了两个根,可以使用upTreeUnion
合并它们
路径压缩的工作原理如下:
找到节点s
的树的根后,您可以再次沿着从s
到根的路径,并设置路径上每个节点到根的parent
指针
更新:
Algorithm(k1,k2){
int i=0,j=0;
int i1,i2;
while (i<max and A[i1 = h1(k1)+i*h2(k1) mod size(A)]->key!=k1){
i++;
}
while (j<max and A[i2 = h1(k2)+j*h2(k2) mod size(A)]->key!=k2){
j++;
}
if (A[i1]->key!=k1) return;
if (A[i2]->key!=k2) return;
pointer node1,node2,root1,root2;
node1=A[i1]->node;
node2=A[i2]->node;
root1=UpTreeFind(node1);
root2=UpTreeFind(node2);
if (root1==root2){
printf("The nodes belong to the same up tree");
return;
}
// path compression
pointer tmp,tmpParent;
tmp = node1;
while (tmp->parent!=root1) {
tmpParent=tmp->parent;
tmp->parent=root1;
tmp=tmpParent;
}
tmp = node2;
while (tmp->parent!=root2) {
tmpParent=tmp->parent;
tmp->parent=root2;
tmp=tmpParent;
}
UpTreeUnion(root1,root2);
}
算法(k1,k2){
int i=0,j=0;
inti1,i2;
while(ikey!=k1){
i++;
}
while(jkey!=k2){
j++;
}
如果(A[i1]->key!=k1)返回;
如果(A[i2]->key!=k2)返回;
指针节点1、节点2、根1、根2;
node1=一个[i1]->节点;
node2=一个[i2]->节点;
root1=向上搜索(node1);
root2=向上搜索(node2);
if(root1==root2){
printf(“节点属于同一上行树”);
返回;
}
//路径压缩
指针tmp,tmpParent;
tmp=节点1;
while(tmp->parent!=root1){
tmpParent=tmp->parent;
tmp->parent=root1;
tmp=tmp租金;
}
tmp=节点2;
while(tmp->parent!=root2){
tmpParent=tmp->parent;
tmp->parent=root2;
tmp=tmp租金;
}
上行联合(root1,root2);
}
是的,对我来说一般都没问题(索引中有一些错误/打字错误)。我用你修改过的代码更新了我的答案-我修改了那些索引并添加了路径压缩。好吧,反正它是伪代码,所以我们不必声明那些字段。如果是一个课程作业,就用自然语言作为假设。至于路径压缩的功能,UpTreeFind函数必须从给定的节点到根节点。从该节点到根节点的路径可能很长。如果压缩此路径,下次调用UpTreeFind时,路径将短得多,因为压缩会将路径上的节点直接连接到根。你们可以在我的图片中看到。更短的路径意味着UpTreeFind将更快地工作。示例-请看我照片上的左树。如果调用UpTreeFind(D),它必须遵循以下路径:D->B->A->E,然后才能找到根(3条边)。现在看看右边的树(使用从D到E的压缩路径):如果在这棵树上调用UpTreeFind(D),它只需要跟随一条边:D->E,然后找到根。因此,路径压缩提高了性能。定义Begging和k,我不理解你的问题。是的,这是最常见的用例。