Merge 不交集的并

Merge 不交集的并,merge,hashtable,union-find,Merge,Hashtable,Union Find,我正在研究支持联合功能的不相交集 降低树木高度的技术: 我们总是将较小的树合并到较大的树上,也就是说,我们使较小树的根指向较大树的根 如果一棵树有更多的节点,它就比另一棵树大 每个节点都是一个带有字段的结构:元素的一些信息、指向父节点的指针“parent”和计数器“count”,仅当节点是根节点并且包含上行树中的节点数时才使用 以下算法合并两个上行树: pointer UpTreeUnion(pointer S,T) { if (S == NULL OR P == NULL) return

我正在研究支持联合功能的不相交集

降低树木高度的技术:

我们总是将较小的树合并到较大的树上,也就是说,我们使较小树的根指向较大树的根

如果一棵树有更多的节点,它就比另一棵树大

每个节点都是一个带有字段的结构:元素的一些信息、指向父节点的指针“parent”和计数器“count”,仅当节点是根节点并且包含上行树中的节点数时才使用

以下算法合并两个上行树:

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,我不理解你的问题。是的,这是最常见的用例。