Skip to content

Commit

Permalink
Updates:
Browse files Browse the repository at this point in the history
- Add Heap interface
- Add BinaryHeap implementation
- Add tests for BinaryHeap
- Refactor list util methods
- Refactor heap util methods
  • Loading branch information
havelessbemore committed May 20, 2021
1 parent c9baa64 commit dba59a5
Show file tree
Hide file tree
Showing 18 changed files with 671 additions and 166 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dastal",
"version": "1.3.1",
"version": "1.4.0",
"description": "Data Structures & Algorithms implementations",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
Expand Down
120 changes: 70 additions & 50 deletions src/heap/binaryHeap.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
import { bubbleUp, heapify, sinkDown } from './heapify';
import { Comparator } from '.';
import { CompareFn } from '..';
import { Heap } from './heap';

export abstract class BinaryHeap<T> implements Heap<T> {
protected _comparator: Comparator<T>;
protected array: Array<T>;

constructor(comparator: Comparator<T>, array: Array<T> = []) {
this._comparator = comparator;
this.array = array;
import { bubbleUp, heapify, sinkDown } from './utils';

/**
*
*/
export class BinaryHeap<T> implements Heap<T> {
/**
* @ignore
*/
protected array: T[];
/**
* @ignore
*/
protected compare: CompareFn<T>;

constructor(compareFn: CompareFn<T>, elements?: Iterable<T>) {
this.compare = compareFn;
this.array = Array.from(elements ?? []);
heapify(this.compare, this.array);
}

protected abstract isAboveOrEqual(a: T, b: T): boolean;
abstract heapify(...iterables: Iterable<T>[]): BinaryHeap<T>;

clear(): void {
this.array.length = 0;
}

comparator(): Comparator<T> {
return this._comparator;
comparator(): CompareFn<T> {
return this.compare;
}

/*
contains(element: T): boolean {
return this.array.indexOf(element) >= 0;
}
Expand All @@ -42,17 +48,32 @@ export abstract class BinaryHeap<T> implements Heap<T> {
// Add the last value to the
// deleted index and update the heap
this.array[index] = last;
sinkDown(index, (a, b) => this.isAboveOrEqual(a, b), this.array);
sinkDown(index, this.compare, this.array);
bubbleUp(index, this.compare, this.array);
return true;
}
*/

merge(heap: Heap<T>): this {
for (const element of heap) {
this.array.push(element);
*dump(): Iterable<T> {
for (let i = 0; i < this.array.length; ++i) {
yield this.array[i];
}
}

merge(elements: Iterable<T>): number {
const array = this.array;
const length = array.length;
try {
for (const element of elements) {
array.push(element);
}
} catch (error) {
throw error;
} finally {
if (length != array.length) {
heapify(this.compare, array);
}
}
heapify((a, b) => this.isAboveOrEqual(a, b), this.array);
return this;
return this.size;
}

peek(): T | undefined {
Expand All @@ -73,7 +94,7 @@ export abstract class BinaryHeap<T> implements Heap<T> {
// Add the last value to
// the root and update the heap
this.array[0] = last!;
sinkDown(0, (a, b) => this.isAboveOrEqual(a, b), this.array);
sinkDown(0, this.compare, this.array);
}

return value;
Expand All @@ -84,60 +105,59 @@ export abstract class BinaryHeap<T> implements Heap<T> {
this.array.push(value);

// Update the heap
bubbleUp(this.array.length - 1, (a, b) => this.isAboveOrEqual(a, b), this.array);
bubbleUp(this.array.length - 1, this.compare, this.array);
return this.size;
}

// Push a new value to the heap and then pop the root
pushPop(value: T): T {
// If empty or value is above or equal to root
if (this.array.length < 1 || this.isAboveOrEqual(value, this.array[0])) {
if (this.array.length < 1 || this.compare(value, this.array[0]) <= 0) {
return value;
}

// Swap the root and value
const root = this.array[0];
this.array[0] = value;
sinkDown(0, (a, b) => this.isAboveOrEqual(a, b), this.array);
sinkDown(0, this.compare, this.array);
return root;
}

// Pop the root of the heap and then push a new value
replace(value: T): T {
// If not empty
if (this.array.length > 0) {
// Swap the root with value
const root = this.array[0];
this.array[0] = value;
value = root;

// Update the heap
sinkDown(0, (a, b) => this.isAboveOrEqual(a, b), this.array);
replace(value: T): T | undefined {
// If empty
if (this.array.length < 1) {
this.array.push(value);
return undefined;
}

// Swap the root with value
const root = this.array[0];
this.array[0] = value;
value = root;

// Update the heap
sinkDown(0, this.compare, this.array);

return value;
}

get size(): number {
return this.array.length;
}

/*
update(element: T): boolean {
const index = this.array.indexOf(element);
[Symbol.iterator](): Iterator<T> {
return Array.from(this.array).sort(this.compare)[Symbol.iterator]();
}

update(curElement: T, newElement: T): boolean {
const index = this.array.indexOf(curElement);
if (index < 0) {
return false;
}
const fn = (a: T, b: T) => this.isAboveOrEqual(a, b);
sinkDown(index, fn, this.array);
bubbleUp(index, fn, this.array);
this.array[index] = newElement;
sinkDown(index, this.compare, this.array);
bubbleUp(index, this.compare, this.array);
return true;
}
*/

[Symbol.iterator](): Iterator<T> {
return Array.from(this.array)
.sort((a, b) => this._comparator.compare(a, b))
[Symbol.iterator]();
}
}
13 changes: 0 additions & 13 deletions src/heap/binaryMaxHeap.ts

This file was deleted.

13 changes: 0 additions & 13 deletions src/heap/binaryMinHeap.ts

This file was deleted.

95 changes: 70 additions & 25 deletions src/heap/heap.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,77 @@
import { Sorted } from '..';

/**
*
*/
export interface Heap<T> extends Iterable<T>, Sorted<T> {
/**
*
*/
clear(): void;
comparator(): Comparator<T>;
heapify(...iterables: Iterable<T>[]): Heap<T>;
merge(heap: Heap<T>): Heap<T>;
/**
*
* @param element
*/
contains(element: T): boolean;
/**
*
* Aka extract, remove
* @param element
*
* @returns
*/
delete(element: T): boolean;
/**
*
*/
dump(): Iterable<T>;
/**
*
* @param elements
* @returns
*/
merge(elements: Iterable<T>): number;
/**
*
* @returns
*/
peek(): T | undefined;
pop(): T | undefined; // Aka extract, delete
/**
*
* @returns
*/
pop(): T | undefined;
/**
*
* @param element
*
* @returns
*/
push(element: T): number; // Aka insert, add
/**
*
* @param element
*
* @returns
*/
pushPop(element: T): T;
replace(element: T): T; // Aka popPush
/**
*
* @param element
*
* @returns
*/
replace(element: T): T | undefined; // Aka popPush
/**
*
*/
readonly size: number;
}

export interface Comparator<T> {
compare: CompareFn<T>;
}

export interface CompareFn<T> {
(a: T, b: T): number;
}

export interface Sortable<T> {
sort: SortFn<T>;
}

export interface SortFn<T> {
(compare: CompareFn<T>): void;
}

export interface Sorted<T> {
comparator(): Comparator<T>;
/**
*
* @param curElement
* @param newElement
*
* @returns
*/
update(curElement: T, newElement: T): boolean;
}
2 changes: 0 additions & 2 deletions src/heap/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
export * from './binaryHeap';
export * from './binaryMaxHeap';
export * from './binaryMinHeap';
export * from './heap';

0 comments on commit dba59a5

Please sign in to comment.