Time complexity
Find min: O(logN)
Merge: O(logN)
Insert: average time is const, worst case is O(N)
A binomial queue of N elements can be built by N successive insertions in O(N) time.
T
w
o
r
s
t
=
O
(
l
o
g
N
)
,
T_{worst} = O(log N),
Tworst=O(logN), but
T
a
m
o
r
t
i
z
e
d
=
2
T_{amortized} = 2
Tamortized=2
methods
left-child-next-sibling
the new tree will be the largest
maintain the subtrees in decreasing order
code
#include"binomialqueue.h"
#include"fatal.h"
#define MAXTREES 25
#define CAPACITY ((1<<MAXTREES)-1)//容量是2^0+2^1+2^3+2^(MAXTREES-1)
typedef struct BinNode *Position;
struct BinNode {
ElementType element;
Position leftChild;
Position nextSibling;
};
struct Collection {
int currentSize;
BinTree theTrees[MAXTREES];
};
BinQueue initialize(void) {
BinQueue h = (BinQueue)malloc(sizeof(struct Collection));
if (h == NULL)
Error("OUT OF MEMORY");
for (int i = 0; i < MAXTREES; i++)
h->theTrees[i] = NULL;
h->currentSize = 0;
return h;
}
ElementType findMin(BinQueue h) {
if (isEmpty(h))
Error("EMPTY HEAP");
ElementType minElem;
int i, j;
for (i = 0, j = 1; j <= h->currentSize; i++, j *= 2) {//找到第一个的二项树的根,j代表i二项树结点的个数,最大的二项树的下一个二项树的结点的个数比currentSize的最大值大1
if (h->theTrees[i] != NULL) {
minElem = h->theTrees[i]->element;
break;
}
}
for (; j <= h->currentSize; i++, j *= 2) {//再和剩下的比较
if (h->theTrees[i] && h->theTrees[i]->element < minElem) {
minElem = h->theTrees[i]->element;
}
}
return minElem;
}
int isEmpty(BinQueue h) {
return h->currentSize == 0;
}
static BinTree combineTrees(BinTree t1, BinTree t2) {
if (t1->element > t2->element)
return combineTrees(t2, t1);
else {
t2->nextSibling = t1->leftChild;//leftchild指向高度高的二项树,高度依次从nextSibling减少
t1->leftChild = t2;
return t1;
}
}
BinQueue merge(BinQueue &h1, BinQueue &h2) {//h2合并到h1当中
if (h1 == h2)
return h1;
BinTree t1, t2;
BinTree carry = NULL;
int carrt_tag;
if (h1->currentSize + h2->currentSize > CAPACITY)
Error("TOO MUCH ELEM");
if (h1->currentSize < h2->currentSize) {
//互换
BinQueue temp;
temp = h1;
h1 = h2;
h2 = temp;
}
h1->currentSize += h2->currentSize;
int h2Size = 0;
for (int i = 0, j = 1; j <= h1->currentSize; i++, j *= 2) {//统计h2中树的数量
if (h2->theTrees[i] != NULL)
h2Size++;
}
for (int i = 0, j = 1; (carry || h2Size) && j <= h1->currentSize; i++, j *= 2) {
t1 = h1->theTrees[i];
t2 = h2->theTrees[i];
if (carry)
carrt_tag = 1;
else
carrt_tag = 0;
switch (!!t1 + 2 * !!t2 + 4 * carrt_tag) {
case 0://t1,t2,carry空
break;
case 1://t1非空
break;
case 2://t2非空
h1->theTrees[i] = t2;
h2->theTrees[i] = NULL;
h2Size--;
break;
case 3://t1,t2非空
carry = combineTrees(t1, t2);
h1->theTrees[i] = NULL;
h2->theTrees[i] = NULL;
h2Size--;
break;
case 4://carry非空
h1->theTrees[i] = carry;
carry = NULL;
break;
case 5://t1,carry非空
carry = combineTrees(t1, carry);
h1->theTrees[i] = NULL;
break;
case 6://t2, carry非空
carry = combineTrees(t2, carry);
h2->theTrees[i] = NULL;
h2Size--;
break;
case 7:
h1->theTrees[i] = carry;
carry = combineTrees(t1, t2);
h2->theTrees[i] = NULL;
h2Size--;
break;
default:
Error("error");
break;
}
}
return h1;
}
void insert(ElementType X, BinQueue h) {
BinTree t1;
BinTree carry = (BinTree)malloc(sizeof(struct BinNode));
if (carry == NULL)
Error("EMPTY MEOERY");
carry->element = X;
carry->leftChild = carry->nextSibling = NULL;
int carrt_tag;
if (h->currentSize + 1 > CAPACITY)
Error("TOO MUCH ELEM");
h->currentSize += 1;
int i = 0;
while (carry != NULL) {
t1 = h->theTrees[i];
if (carry)
carrt_tag = 1;
else
carrt_tag = 0;
switch (!!t1 + 2 * !!carrt_tag) {
case 0://t1,t2,carry空
break;
case 1://t1非空
break;
case 2://carry非空
h->theTrees[i] = carry;
carry = NULL;
break;
case 3://t1,carry非空
carry = combineTrees(t1, carry);
h->theTrees[i] = NULL;
break;
default:
Error("error");
break;
}
i++;
}
}
BinQueue deleteMin(BinQueue h) {
if (isEmpty(h))
Error("EMPTY HEAP");
int minTree;
ElementType minElem;
int i, j;
for (i = 0, j = 1; j <= h->currentSize; i++, j *= 2) {
if (h->theTrees[i] != NULL) {
minElem = h->theTrees[i]->element;
minTree = i;
i++;
break;
}
}
for (; j <= h->currentSize; i++, j *= 2) {
if (h->theTrees[i] && h->theTrees[i]->element < minElem) {
minElem = h->theTrees[i]->element;
minTree = i;
}
}
BinQueue deleteQueue = initialize();
deleteQueue->currentSize = (1 << minTree) - 1;//mintree的儿子有mintree个,结点个数加起来就是 (1 << minTree) - 1
Position p = h->theTrees[minTree]->leftChild;//高度从大到小
for (int i = minTree - 1; i >= 0; i--, p = p->nextSibling) {
deleteQueue->theTrees[i] = p;
}
free(h->theTrees[minTree]);
h->theTrees[minTree] = NULL;
h->currentSize -= (deleteQueue->currentSize + 1);
merge(h, deleteQueue);
free(deleteQueue);
return h;
}