原创没看懂:http://blog.csdn.net/pi9nc/article/details/11841995
转载看懂了:http://blog.csdn.net/luofeixiongsix/article/details/50640668
一、特性:
配对堆是一种比较实用的斐波那契堆,它的优势是在进行DecreaseKey的时候速度快于其他堆结构。
1.在这里,每个顶点可以接很多的孩子,在这里的实现类似与二项队列。使用左孩子与兄弟
2. 加了一个Prev指针,指向前向节点,可以指向父亲,也可以指向兄弟。
其实现如下图所示:
二、基础操作:
这里最基础的操作就是合并堆,由于一个根节点可以接许多的孩子,我们合并的时候,只需要让较小的根节点成为父亲,较大的根成为左孩子即可。
编码实现:
合并:
- PairHeap CompareAndLink(PairHeap H1, PairHeap H2)
- {
- if(H2 == NULL)
- return H1;
- else if(H1 ->Element <= H2->Element)
- {
- H2->Prev = H1;
- H1->NextSibling = H2->NextSibling;
- if(H1->NextSibling != NULL)
- H1->NextSibling->Prev = H1;
- H2->NextSibling = H1->Left;
- if(H2->NextSibling != NULL)
- H2->NextSibling->Prev = H2;
- H1->Left = H2;
- return H1;
- }
- else
- {
- H2->Prev = H1->Prev;
- H1->Prev = H2;
- H1->NextSibling = H2->Left;
- if(H1->NextSibling != NULL)
- H1->NextSibling->Prev = H1;
- H2->Left = H1;
- return H2;
- }
- }
插入:
- PairHeap insert(ElementType X, PairHeap H, Position * Loc)
- {
- PairHeap NewNode;
- NewNode = (PairHeap)malloc(sizeof(struct PairNode));
- if(NewNode == NULL)
- exit(1);
- NewNode->Element = X;
- NewNode->Left = NewNode->NextSibling = NewNode ->Prev = NULL;
- *Loc = NewNode;
- if(H == NULL)
- return NewNode;
- return CompareAndLink(H, NewNode);
- }
删除:
- PairHeap deleteMin(ElementType * Min, PairHeap H)
- {
- if(H == NULL)
- return H;
- PairHeap NewRoot;
- *Min = H->Element;
- if(H->Left != NULL)
- NewRoot = CombineSiblings(H->Left);
- free(H);
- return NewRoot;
- }
- PairHeap CombineSiblings(Position FirstSibling)
- {
- static Position TreeArray[100];
- int i, j, Num;
- if(FirstSibling == NULL)
- return FirstSibling;
- for(Num =0; FirstSibling != NULL; Num++)
- {
- TreeArray[Num] = FirstSibling;
- FirstSibling->Prev->NextSibling = NULL;
- FirstSibling = FirstSibling->NextSibling;
- }
- TreeArray[Num] = NULL;
- for(i =0; i+1<Num; i +=2)
- TreeArray[i] = CompareAndLink(TreeArray[i], TreeArray[i+1]);
- j =i-2;
- if(j == Num -3)
- TreeArray[j] = CompareAndLink(TreeArray[j], TreeArray[j+2]);
- for(; j>=2; j-=2)
- TreeArray[j-2] = CompareAndLink(TreeArray[j-2], TreeArray[j]);
- return TreeArray[0];
- }
减小键值:
- PairHeap DecreaseKey(Position P, ElementType Delta, PairHeap H)
- {
- if(Delta < 0)
- return H;
- P->Element -= Delta;
- if(P == H)
- return H;
- if(P->NextSibling != NULL)
- P->NextSibling->Prev = P->Prev;
- if(P->Prev->Left == P)
- P->Prev ->Left = P->NextSibling;
- else
- P->Prev->NextSibling = P->NextSibling;
- P->NextSibling = NULL;
- return CompareAndLink(H, P);
- }
测试:
左图是插入节点之后,形成的配对堆,可见,只有0是根,其他的都是孩子。
右图是删除根节点0之后,形成的新配对堆。