1 | import { LinkNode } from "../linklist/LinkNode";
|
2 | function compareFn(a, b) {
|
3 | return a <= b;
|
4 | }
|
5 | export class BinomialHeap {
|
6 | constructor(compare = compareFn) {
|
7 | this.compare = compare;
|
8 | this.count = 0;
|
9 | }
|
10 | get Count() {
|
11 | return this.count;
|
12 | }
|
13 | get Head() {
|
14 | return this.head;
|
15 | }
|
16 | setHead(value) {
|
17 | this.head = new LinkNode({
|
18 | value,
|
19 | degree: 0,
|
20 | });
|
21 | this.count = 1;
|
22 | }
|
23 | clear() {
|
24 | this.head = null;
|
25 | this.count = 0;
|
26 | }
|
27 | isEmpty() {
|
28 | return !this.head;
|
29 | }
|
30 | insert(value) {
|
31 | const heap = new BinomialHeap();
|
32 | heap.setHead(value);
|
33 | const newNode = heap.Head;
|
34 | this.union(heap);
|
35 | return newNode;
|
36 | }
|
37 | deleteExtremum() {
|
38 | if (!this.head) {
|
39 | return null;
|
40 | }
|
41 | const deleteNode = this._findExtremum();
|
42 | if (!deleteNode.minPrev) {
|
43 | this.head = deleteNode.minNode.Next;
|
44 | }
|
45 | else {
|
46 | deleteNode.minPrev.setNext(deleteNode.minNode.Next);
|
47 | }
|
48 | let child = deleteNode.minNode.Value.child;
|
49 | const newHead = child;
|
50 | while (child) {
|
51 | child.Value.parent = null;
|
52 | child = child.Next;
|
53 | }
|
54 | const heap = new BinomialHeap(this.compare);
|
55 | heap.head = newHead;
|
56 | this.union(heap);
|
57 | this.count--;
|
58 | return deleteNode.minNode.Value.value;
|
59 | }
|
60 | _findExtremum() {
|
61 | let next = this.head.Next;
|
62 | let minNode = this.head;
|
63 | let prev = this.head;
|
64 | let minPrev = null;
|
65 | let min = minNode.Value.value;
|
66 | while (next) {
|
67 | if (!this.compare(min, next.Value.value)) {
|
68 | minPrev = prev;
|
69 | minNode = next;
|
70 | min = minNode.Value.value;
|
71 | }
|
72 | prev = next;
|
73 | next = next.Next;
|
74 | }
|
75 | return { minNode, minPrev };
|
76 | }
|
77 | findExtremum() {
|
78 | if (!this.head) {
|
79 | return null;
|
80 | }
|
81 | return this._findExtremum().minNode.Value.value;
|
82 | }
|
83 | union(heap) {
|
84 | if (!heap) {
|
85 | return this;
|
86 | }
|
87 | this.count += heap.Count;
|
88 | let newHead = this.mergeHeaps(heap);
|
89 | if (!newHead) {
|
90 | return this;
|
91 | }
|
92 | this.head = null;
|
93 | heap.head = null;
|
94 | let prev;
|
95 | let curr = newHead;
|
96 | let next = newHead.Next;
|
97 | while (next) {
|
98 | if (next.Value.degree !== curr.Value.degree ||
|
99 | (next.Next && next.Next.Value.degree === curr.Value.degree)) {
|
100 | prev = curr;
|
101 | curr = next;
|
102 | }
|
103 | else {
|
104 | if (this.compare(curr.Value.value, next.Value.value)) {
|
105 | curr.setNext(next.Next);
|
106 | this.link(curr, next);
|
107 | }
|
108 | else {
|
109 | if (!prev) {
|
110 | newHead = next;
|
111 | }
|
112 | else {
|
113 | prev.setNext(next);
|
114 | }
|
115 | this.link(next, curr);
|
116 | curr = next;
|
117 | }
|
118 | }
|
119 | next = curr.Next;
|
120 | }
|
121 | this.head = newHead;
|
122 | return this;
|
123 | }
|
124 | link(tomerge, frommerge) {
|
125 | frommerge.setNext(tomerge.Value.child);
|
126 | frommerge.Value.parent = tomerge;
|
127 | tomerge.Value.child = frommerge;
|
128 | tomerge.Value.degree++;
|
129 | }
|
130 | mergeHeaps(heap) {
|
131 | let thisHead = this.head;
|
132 | let thatHead = heap.Head;
|
133 | if (!thisHead) {
|
134 | return heap.head;
|
135 | }
|
136 | if (!thatHead) {
|
137 | return this.head;
|
138 | }
|
139 | let newHead;
|
140 | if (thisHead.Value.degree <= thatHead.Value.degree) {
|
141 | newHead = this.head;
|
142 | thisHead = thisHead.Next;
|
143 | }
|
144 | else {
|
145 | newHead = heap.head;
|
146 | thatHead = thatHead.Next;
|
147 | }
|
148 | let temp = newHead;
|
149 | while (thisHead && thatHead) {
|
150 | if (thisHead.Value.degree <= thatHead.Value.degree) {
|
151 | temp.setNext(thisHead);
|
152 | thisHead = thisHead.Next;
|
153 | }
|
154 | else {
|
155 | temp.setNext(thatHead);
|
156 | thatHead = thatHead.Next;
|
157 | }
|
158 | temp = temp.Next;
|
159 | }
|
160 | temp.setNext(thisHead ? thisHead : thatHead);
|
161 | return newHead;
|
162 | }
|
163 | }
|