Add CircularQueue.ts and test file

This commit is contained in:
2025-07-02 18:34:55 -04:00
parent 18be03bfa6
commit 4fbc30a264
2 changed files with 268 additions and 5 deletions

View File

@@ -2,6 +2,8 @@ export class CircularQueue<T> {
private startIndex: number;
private endIndex: number;
private _data: T[];
private _size: number;
private _capacity: number;
constructor(
size: number,
@@ -10,18 +12,103 @@ export class CircularQueue<T> {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#sparse_arrays
this._data = new Array<T>(size);
this.startIndex = 0;
this.endIndex = size - 1;
this.endIndex = 0;
this._size = 0;
this._capacity = size;
}
size = (): number => this._size;
get = (index: number): T | undefined => {
if (index < 0 || index >= this._size) {
return undefined;
}
const actualIndex = (this.startIndex + index) % this._capacity;
return this._data[actualIndex];
};
appendWithSorting = (
data: T,
sortingCallback: ((a: T, b: T) => number) | undefined
sortingCallback: (a: T, b: T) => number
) => {
// In case something is added that's not sorted, the sortingCallback
// will be used to sort
if (this._size === 0) {
this._data[this.startIndex] = data;
this._size = 1;
this.endIndex = this.startIndex;
return;
}
if (this._size < this._capacity) {
this.endIndex = (this.endIndex + 1) % this._capacity;
this._data[this.endIndex] = data;
this._size++;
} else {
this.startIndex = (this.startIndex + 1) % this._capacity;
this.endIndex = (this.endIndex + 1) % this._capacity;
this._data[this.endIndex] = data;
}
this.sortData(sortingCallback);
}
popFront = (data: T) => {
popFront = () => {
if (this._size === 0) {
return;
}
this._data[this.startIndex] = undefined as any;
if (this._size === 1) {
this._size = 0;
this.startIndex = 0;
this.endIndex = 0;
} else {
this.startIndex = (this.startIndex + 1) % this._capacity;
this._size--;
}
}
binarySearch = <K>(
searchKey: K,
keyExtractor: (item: T) => K
): T | undefined => {
if (this._size === 0) {
return undefined;
}
let left = 0;
let right = this._size - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const midItem = this.get(mid)!;
const midKey = keyExtractor(midItem);
if (midKey === searchKey) {
return midItem;
} else if (midKey < searchKey) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return undefined;
}
private sortData = (sortingCallback: (a: T, b: T) => number) => {
const items: T[] = [];
for (let i = 0; i < this._size; i++) {
const item = this.get(i);
if (item !== undefined) {
items.push(item);
}
}
items.sort(sortingCallback);
for (let i = 0; i < items.length; i++) {
const actualIndex = (this.startIndex + i) % this._capacity;
this._data[actualIndex] = items[i];
}
};
}