mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-13 01:04:03 +00:00
fix: Fix bug in BinaryTree.print to support undefined, null, and NIL. Fix #106
This commit is contained in:
parent
0a8b9265cc
commit
9ace395564
|
@ -1681,20 +1681,14 @@ export class BinaryTree<
|
|||
beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,
|
||||
options?: BinaryTreePrintOptions
|
||||
): string {
|
||||
const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
|
||||
const opts = { isShowUndefined: false, isShowNull: true, isShowRedBlackNIL: false, ...options };
|
||||
beginRoot = this.ensureNode(beginRoot);
|
||||
let output = '';
|
||||
if (!beginRoot) return output;
|
||||
|
||||
if (opts.isShowUndefined)
|
||||
output += `U for undefined
|
||||
`;
|
||||
if (opts.isShowNull)
|
||||
output += `N for null
|
||||
`;
|
||||
if (opts.isShowRedBlackNIL)
|
||||
output += `S for Sentinel Node(NIL)
|
||||
`;
|
||||
if (opts.isShowUndefined) output += `U for undefined\n`;
|
||||
if (opts.isShowNull) output += `N for null\n`;
|
||||
if (opts.isShowRedBlackNIL) output += `S for Sentinel Node(NIL)\n`;
|
||||
|
||||
const display = (root: OptBTNOrNull<NODE>): void => {
|
||||
const [lines, , ,] = this._displayAux(root, opts);
|
||||
|
@ -1709,6 +1703,10 @@ export class BinaryTree<
|
|||
return output;
|
||||
}
|
||||
|
||||
override print(options?: BinaryTreePrintOptions, beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root) {
|
||||
console.log(this.toVisual(beginRoot, options));
|
||||
}
|
||||
|
||||
protected _dfs<C extends BTNCallback<NODE>>(
|
||||
callback?: C,
|
||||
pattern?: DFSOrderPattern,
|
||||
|
|
|
@ -310,28 +310,26 @@ export class BST<
|
|||
if (!isBalanceAdd) {
|
||||
for (const kve of keysOrNodesOrEntriesOrRaws) {
|
||||
const value = valuesIterator?.next().value;
|
||||
const nn = this.add(kve, value);
|
||||
inserted.push(nn);
|
||||
inserted.push(this.add(kve, value));
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
|
||||
const realBTNExemplars: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];
|
||||
|
||||
const isRealBTNExemplar = (
|
||||
kve: BTNKeyOrNodeOrEntry<K, V, NODE> | R
|
||||
): kve is BTNPureKeyOrNodeOrEntry<K, V, NODE> => {
|
||||
if (kve === undefined || kve === null) return false;
|
||||
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
|
||||
};
|
||||
const realBTNExemplars: {
|
||||
key: R | BTNKeyOrNodeOrEntry<K, V, NODE>;
|
||||
value: V | undefined;
|
||||
orgIndex: number;
|
||||
}[] = [];
|
||||
|
||||
let i = 0;
|
||||
for (const kve of keysOrNodesOrEntriesOrRaws) {
|
||||
if (isRealBTNExemplar(kve)) realBTNExemplars.push(kve);
|
||||
realBTNExemplars.push({ key: kve, value: valuesIterator?.next().value, orgIndex: i });
|
||||
i++;
|
||||
}
|
||||
|
||||
let sorted: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];
|
||||
let sorted: { key: R | BTNKeyOrNodeOrEntry<K, V, NODE>; value: V | undefined; orgIndex: number }[] = [];
|
||||
|
||||
sorted = realBTNExemplars.sort((a, b) => {
|
||||
sorted = realBTNExemplars.sort(({ key: a }, { key: b }) => {
|
||||
let keyA: K | undefined | null, keyB: K | undefined | null;
|
||||
if (this.isEntry(a)) keyA = a[0];
|
||||
else if (this.isRealNode(a)) keyA = a.key;
|
||||
|
@ -355,12 +353,12 @@ export class BST<
|
|||
return 0;
|
||||
});
|
||||
|
||||
const _dfs = (arr: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[]) => {
|
||||
const _dfs = (arr: { key: R | BTNKeyOrNodeOrEntry<K, V, NODE>; value: V | undefined; orgIndex: number }[]) => {
|
||||
if (arr.length === 0) return;
|
||||
|
||||
const mid = Math.floor((arr.length - 1) / 2);
|
||||
const newNode = this.add(arr[mid]);
|
||||
inserted.push(newNode);
|
||||
const { key, value, orgIndex } = arr[mid];
|
||||
inserted[orgIndex] = this.add(key, value);
|
||||
_dfs(arr.slice(0, mid));
|
||||
_dfs(arr.slice(mid + 1));
|
||||
};
|
||||
|
@ -374,8 +372,8 @@ export class BST<
|
|||
const [l, r] = popped;
|
||||
if (l <= r) {
|
||||
const m = l + Math.floor((r - l) / 2);
|
||||
const newNode = this.add(sorted[m]);
|
||||
inserted.push(newNode);
|
||||
const { key, value, orgIndex } = sorted[m];
|
||||
inserted[orgIndex] = this.add(key, value);
|
||||
stack.push([m + 1, r]);
|
||||
stack.push([l, m - 1]);
|
||||
}
|
||||
|
|
|
@ -292,6 +292,26 @@ describe('AVLTree', () => {
|
|||
// You can add more specific assertions to check the tree's balance and structure.
|
||||
});
|
||||
|
||||
it('should addMany undefined and null', () => {
|
||||
const avl = new AVLTree<number, string>();
|
||||
const addManyWithUndefined = avl.addMany([1, undefined, 3]);
|
||||
expect(addManyWithUndefined).toEqual([true, false, true]);
|
||||
expect(avl.get(undefined)).toBe(undefined);
|
||||
const addManyWithNull = avl.addMany([1, null, 3, 4]);
|
||||
expect(addManyWithNull).toEqual([true, false, true, true]);
|
||||
const addManyEntriesWithNull = avl.addMany([
|
||||
[1, '1'],
|
||||
[null, 'null'],
|
||||
[3, '3'],
|
||||
[4, '4']
|
||||
]);
|
||||
expect(addManyEntriesWithNull).toEqual([true, false, true, true]);
|
||||
expect(avl.get(null)).toBe(undefined);
|
||||
const node0 = avl.add(0, '0');
|
||||
expect(node0).toBe(true);
|
||||
expect(avl.get(0)).toBe('0');
|
||||
});
|
||||
|
||||
it('should balance the tree using _balanceLR when nodes are deleted', () => {
|
||||
const avlTree = new AVLTree();
|
||||
avlTree.add([10, 'A']);
|
||||
|
|
|
@ -105,6 +105,27 @@ describe('BinaryTree addMany', () => {
|
|||
expect(tree.getNodeByKey(4)?.value).toBe(44);
|
||||
expect(tree.getNodeByKey(1)?.value).toBe(1);
|
||||
});
|
||||
|
||||
it('should addMany undefined and null', () => {
|
||||
const binaryTree = new BinaryTree<number, string>();
|
||||
const addManyWithUndefined = binaryTree.addMany([1, undefined, 3]);
|
||||
expect(addManyWithUndefined).toEqual([true, false, true]);
|
||||
expect(binaryTree.get(undefined)).toBe(undefined);
|
||||
const addManyWithNull = binaryTree.addMany([1, null, 3, 4]);
|
||||
expect(addManyWithNull).toEqual([true, true, true, true]);
|
||||
const addManyEntriesWithNull = binaryTree.addMany([
|
||||
[1, '1'],
|
||||
[null, 'null'],
|
||||
[3, '3'],
|
||||
[4, '4']
|
||||
]);
|
||||
expect(addManyEntriesWithNull).toEqual([true, true, true, true]);
|
||||
expect(binaryTree.get(null)).toBe(undefined);
|
||||
expect(binaryTree.getNode(null)).toBe(null);
|
||||
const node0 = binaryTree.add(0, '0');
|
||||
expect(node0).toBe(true);
|
||||
expect(binaryTree.get(0)).toBe('0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('BinaryTree', () => {
|
||||
|
|
|
@ -16,22 +16,27 @@ describe('BST operations test', () => {
|
|||
expect(isAdd0).toBe(true);
|
||||
expect(bst.get(0)).toBe('0');
|
||||
});
|
||||
|
||||
it('should addMany undefined and null', () => {
|
||||
const bst = new BST<number, string>();
|
||||
const addManyWithUndefined = bst.addMany([1, undefined, 3]);
|
||||
// TODO
|
||||
// expect(addManyWithUndefined).toEqual([true, false, true]);
|
||||
expect(addManyWithUndefined).toEqual([true, true]);
|
||||
expect(addManyWithUndefined).toEqual([true, false, true]);
|
||||
expect(bst.get(undefined)).toBe(undefined);
|
||||
const addManyWithNull = bst.addMany([1, null, 3, 4]);
|
||||
// TODO
|
||||
// expect(addManyWithNull).toEqual([false, false, false, true]);
|
||||
expect(addManyWithNull).toEqual([true, true, true]);
|
||||
expect(addManyWithNull).toEqual([true, false, true, true]);
|
||||
const addManyEntriesWithNull = bst.addMany([
|
||||
[1, '1'],
|
||||
[null, 'null'],
|
||||
[3, '3'],
|
||||
[4, '4']
|
||||
]);
|
||||
expect(addManyEntriesWithNull).toEqual([true, false, true, true]);
|
||||
expect(bst.get(null)).toBe(undefined);
|
||||
const node0 = bst.add(0, '0');
|
||||
expect(node0).toBe(true);
|
||||
expect(bst.get(0)).toBe('0');
|
||||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const bst = new BST<number, number>();
|
||||
expect(bst).toBeInstanceOf(BST);
|
||||
|
|
Loading…
Reference in a new issue