1 | import { BasicBinaryTreeNode } from "../tree/basic-binary-tree/BasicBinaryTreeNode";
|
2 | function compareFn(a, b) {
|
3 | return a <= b;
|
4 | }
|
5 | export class LeftistTreeNode extends BasicBinaryTreeNode {
|
6 | constructor(value, rank) {
|
7 | super(value);
|
8 | this.rank = rank;
|
9 | }
|
10 | set Rank(rank) {
|
11 | this.rank = rank;
|
12 | }
|
13 | get Rank() {
|
14 | return this.rank;
|
15 | }
|
16 | }
|
17 | export class LeftistTree {
|
18 | constructor(compare = compareFn, value) {
|
19 | this.compare = compare;
|
20 | this.count = 0;
|
21 | if (typeof value !== "undefined") {
|
22 | this.root = new LeftistTreeNode(value, 0);
|
23 | this.count = 1;
|
24 | }
|
25 | }
|
26 | get Root() {
|
27 | return this.root;
|
28 | }
|
29 | get Count() {
|
30 | return this.count;
|
31 | }
|
32 | isEmpty() {
|
33 | return !this.root;
|
34 | }
|
35 | fixNode(node) {
|
36 | const left = node.Left;
|
37 | const right = node.Right;
|
38 | if (left && right && left.Rank < right.Rank) {
|
39 | const temp = node.Right;
|
40 | node.setRight(node.Left);
|
41 | node.setLeft(temp);
|
42 | }
|
43 | else if (node.Right && !node.Left) {
|
44 | node.setLeft(node.Right);
|
45 | node.setRight(null);
|
46 | }
|
47 | if (node.Right) {
|
48 | node.Rank = node.Right.Rank + 1;
|
49 | }
|
50 | else {
|
51 | node.Rank = 0;
|
52 | }
|
53 | }
|
54 | _merge(root1, root2) {
|
55 | if (!root1) {
|
56 | return root2;
|
57 | }
|
58 | if (!root2) {
|
59 | return root1;
|
60 | }
|
61 | if (!this.compare(root1.Value, root2.Value)) {
|
62 | const temp = root2;
|
63 | root2 = root1;
|
64 | root1 = temp;
|
65 | }
|
66 | root1.setRight(this._merge(root1.Right, root2));
|
67 | this.fixNode(root1);
|
68 | return root1;
|
69 | }
|
70 | merge(tree2) {
|
71 | if (!tree2 || tree2.isEmpty()) {
|
72 | return this;
|
73 | }
|
74 | if (!this.root) {
|
75 | this.root = tree2.Root;
|
76 | this.count = tree2.Count;
|
77 | return this;
|
78 | }
|
79 | const root1 = this.Root;
|
80 | const root2 = tree2.Root;
|
81 | this.root = this._merge(root1, root2);
|
82 | this.count += tree2.Count;
|
83 | return this;
|
84 | }
|
85 | findExtremum() {
|
86 | if (!this.root) {
|
87 | return null;
|
88 | }
|
89 | return this.root.Value;
|
90 | }
|
91 | insert(value) {
|
92 | const node = new LeftistTree(this.compare, value);
|
93 | this.merge(node);
|
94 | return node;
|
95 | }
|
96 | deleteExtremum() {
|
97 | if (!this.root) {
|
98 | return null;
|
99 | }
|
100 | const value = this.root.Value;
|
101 | this.root = this._merge(this.root.Left, this.root.Right);
|
102 | this.count--;
|
103 | return value;
|
104 | }
|
105 | }
|