UNPKG

4.86 kBJavaScriptView Raw
1export class Heap {
2 constructor() {
3 this.container = [];
4 }
5 get Size() {
6 return this.container.length;
7 }
8 getLeftChildIndex(parent) {
9 return (2 * parent) + 1;
10 }
11 getRigthChildIndex(parent) {
12 return (2 * parent) + 2;
13 }
14 getParentIndex(index) {
15 return Math.floor((index - 1) / 2);
16 }
17 getLeftChild(parent) {
18 return this.container[this.getLeftChildIndex(parent)];
19 }
20 getRightChild(parent) {
21 return this.container[this.getRigthChildIndex(parent)];
22 }
23 getParent(index) {
24 return this.container[this.getParentIndex(index)];
25 }
26 hasLeftChild(parent) {
27 return this.getLeftChildIndex(parent) < this.container.length;
28 }
29 hasRightChild(parent) {
30 return this.getRigthChildIndex(parent) < this.container.length;
31 }
32 hasParent(index) {
33 return this.getParentIndex(index) >= 0;
34 }
35 swap(indexOne, indexTwo) {
36 const temp = this.container[indexTwo];
37 this.container[indexTwo] = this.container[indexOne];
38 this.container[indexOne] = temp;
39 }
40 heapifyUp(customStartIndex) {
41 let currentIndex = customStartIndex || this.container.length - 1;
42 while (this.hasParent(currentIndex) && !this.compare(this.getParent(currentIndex), this.container[currentIndex])) {
43 this.swap(currentIndex, this.getParentIndex(currentIndex));
44 currentIndex = this.getParentIndex(currentIndex);
45 }
46 }
47 heapifyDown(customStartIndex) {
48 let currentIndex = customStartIndex || 0;
49 let nextIndex = null;
50 while (this.hasLeftChild(currentIndex)) {
51 if (this.hasRightChild(currentIndex)
52 && this.compare(this.getRightChild(currentIndex), this.getLeftChild(currentIndex))) {
53 nextIndex = this.getRigthChildIndex(currentIndex);
54 }
55 else {
56 nextIndex = this.getLeftChildIndex(currentIndex);
57 }
58 if (this.compare(this.container[currentIndex], this.container[nextIndex])) {
59 break;
60 }
61 this.swap(currentIndex, nextIndex);
62 currentIndex = nextIndex;
63 }
64 }
65 poll() {
66 if (this.container.length === 0) {
67 return null;
68 }
69 if (this.container.length === 1) {
70 return this.container.pop();
71 }
72 const item = this.container[0];
73 this.container[0] = this.container.pop();
74 this.heapifyDown();
75 return item;
76 }
77 peek() {
78 if (this.container.length === 0) {
79 return null;
80 }
81 return this.container[0];
82 }
83 add(item) {
84 this.container.push(item);
85 this.heapifyUp();
86 return this;
87 }
88 remove(item) {
89 const numberOfItemsToRemove = this.findAll(item).length;
90 for (let iteration = 0; iteration < numberOfItemsToRemove; iteration += 1) {
91 const indexToRemove = this.findAllIndex(item).pop();
92 if (indexToRemove === (this.container.length - 1)) {
93 this.container.pop();
94 }
95 else {
96 this.container[indexToRemove] = this.container.pop();
97 const parentItem = this.getParent(indexToRemove);
98 if (this.hasLeftChild(indexToRemove) &&
99 (!parentItem || this.compare(parentItem, this.container[indexToRemove]))) {
100 this.heapifyDown(indexToRemove);
101 }
102 else {
103 this.heapifyUp(indexToRemove);
104 }
105 }
106 }
107 return numberOfItemsToRemove > 0;
108 }
109 toString() {
110 return this.container.toString();
111 }
112 isEmpty() {
113 return !this.container.length;
114 }
115 find(arg) {
116 let temp = null;
117 for (let index = 0; index < this.container.length; index++) {
118 const element = this.container[index];
119 const match = typeof arg === "function" ? arg(element) : arg === element;
120 if (match) {
121 temp = element;
122 break;
123 }
124 }
125 return temp;
126 }
127 findAll(arg) {
128 const temp = [];
129 this.container.forEach(item => {
130 const match = typeof arg === "function" ? arg(item) : arg === item;
131 if (match) {
132 temp.push(item);
133 }
134 });
135 return temp;
136 }
137 clear() {
138 this.container.length = 0;
139 }
140 entries() {
141 return [...this.container];
142 }
143 findAllIndex(arg) {
144 const temp = [];
145 this.container.forEach((item, index) => {
146 const match = typeof arg === "function" ? arg(item) : arg === item;
147 if (match) {
148 temp.push(index);
149 }
150 });
151 return temp;
152 }
153}