-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpairing-heap.ts
109 lines (102 loc) · 2.35 KB
/
pairing-heap.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
export class HeapNode {
constructor(
public weight: number,
public left: HeapNode | null = null,
public sibling: HeapNode | null = null
) {}
}
export function addChild(currNode: HeapNode, newNode: HeapNode) {
if (currNode.left === null) {
currNode.left = newNode;
} else {
let oldChildren = currNode.left;
currNode.left = newNode;
newNode.sibling = oldChildren;
}
return currNode;
}
export function merge(
A: Optional<HeapNode>,
B: Optional<HeapNode>
): Optional<HeapNode> {
if (!A) return B;
if (!B) return A;
return A.weight < B.weight ? addChild(A, B) : addChild(B, A);
}
export function toString(q: any) {
if (!q) {
return '';
}
let res = '';
if (q.left) {
res += `${q.weight}>(${toString(q.left)})`;
} else {
res += q.weight;
}
while ((q = q.sibling)) {
if (q.left) {
res += ` ${q.weight}>(${toString(q.left)})`;
continue;
}
res += ' ' + q.weight;
}
return res;
}
function link(node1: any, node2: any) {
node1.sibling = null;
node2.sibling = null;
return merge(node1, node2) as HeapNode;
}
function push(link: HeapNode, value: any) {
link.sibling = value;
link = link?.sibling as HeapNode;
return link;
}
export function MergePass(
iteratorNode: Optional<HeapNode>,
firstPass = true
): Optional<HeapNode> {
if (!iteratorNode || !iteratorNode?.sibling) {
return merge(iteratorNode, iteratorNode?.sibling);
}
let next = iteratorNode.sibling.sibling;
let result = link(iteratorNode, iteratorNode.sibling);
let resultRoot = result;
while (next?.sibling) {
let node1 = next;
let node2 = next?.sibling;
next = node2.sibling;
const res = link(node1, node2);
result = push(result, res);
}
if (next) {
result = push(result, next);
}
return firstPass ? MergePass(resultRoot, false) : resultRoot;
}
type Optional<T> = T | undefined | null;
export function createHeap() {
let root: Optional<HeapNode>;
return {
get root() {
return root;
},
pop() {
if (root === null) {
return null;
}
const removed = root?.weight;
root = MergePass(root?.left as HeapNode);
return removed;
},
push(value: number) {
root = merge(root, new HeapNode(value));
},
top() {
return root?.weight;
},
join(node: HeapNode) {
root = merge(root, node);
},
};
}