-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added ordinal trees, may need fixing
- Loading branch information
Peter Hovanec
committed
Nov 16, 2024
1 parent
6481472
commit 66f53b9
Showing
5 changed files
with
206 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./trie/index"; | ||
export * from "./trie/index"; | ||
export * from "./ordinalTree/index"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
|
||
|
||
class OrdinalNode { | ||
constructor(value) { | ||
this.value = value; | ||
this.children = []; | ||
this.parent = null; | ||
} | ||
|
||
addChild(childNode) { | ||
childNode.parent = this; | ||
this.children.push( childNode); | ||
} | ||
|
||
removeChild(childNode) { | ||
const index = this.children.indexOf(childNode); | ||
if (index > -1) { | ||
this.children.splice(index, 1); | ||
childNode.parent = null; | ||
} | ||
} | ||
|
||
getChildAt(index) { | ||
return this.children[index]; | ||
} | ||
} | ||
|
||
export default OrdinalNode; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
|
||
|
||
import OrdinalNode from "./OrdinalNode"; | ||
|
||
class OrdinalTree { | ||
constructor() { | ||
this.root = null; | ||
} | ||
|
||
|
||
add(value, parentValue = null) { | ||
const newNode = new OrdinalNode(value); | ||
if (this.root === null) { | ||
this.root = newNode; | ||
} else { | ||
const parent = this.findNode(this.root, parentValue); | ||
if (parent) { | ||
parent.addChild(newNode); | ||
} else { | ||
console.error("Parent not found"); | ||
} | ||
} | ||
} | ||
|
||
|
||
findNode(currentNode, value) { | ||
if (currentNode.value === value) { | ||
return currentNode; | ||
} | ||
|
||
for (const child of currentNode.children) { | ||
const foundNode = this.findNode(child, value); | ||
if (foundNode) { | ||
return foundNode; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
|
||
traverse(callback) { | ||
const traverseNode = (node) => { | ||
callback(node); | ||
node.children.forEach(traverseNode); | ||
}; | ||
if (this.root) { | ||
traverseNode(this.root); | ||
} | ||
} | ||
|
||
} | ||
|
||
export default OrdinalTree; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
|
||
export { default as OrdinalTree } from "./OrdinalTree"; | ||
export { default as OrdinalNode } from "./OrdinalNode"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
|
||
|
||
import { OrdinalTree, OrdinalNode } from "../src/ordinalTree/index"; | ||
|
||
describe("OrdinalTree", () => { | ||
let tree; | ||
|
||
beforeEach(() => { | ||
tree = new OrdinalTree(); | ||
}); | ||
|
||
it("should create a tree with a root node", () => { | ||
tree.add("Root"); | ||
expect(tree.root.value).toBe("Root"); | ||
expect(tree.root.children.length).toBe(0); | ||
}); | ||
|
||
it("should add children to the root node", () => { | ||
tree.add("Root"); | ||
tree.add("Child 1", "Root"); | ||
tree.add("Child 2", "Root"); | ||
|
||
expect(tree.root.children.length).toBe(2); | ||
expect(tree.root.children[0].value).toBe("Child 1"); | ||
expect(tree.root.children[1].value).toBe("Child 2"); | ||
}); | ||
|
||
|
||
|
||
it("should retrieve a child at a specific index", () => { | ||
tree.add("Root"); | ||
tree.add("Child 1", "Root"); | ||
tree.add("Child 2", "Root"); | ||
|
||
const childAtIndex = tree.root.getChildAt(1); | ||
expect(childAtIndex.value).toBe("Child 2"); | ||
}); | ||
|
||
it("should add grandchildren to a child node", () => { | ||
tree.add("Root"); | ||
tree.add("Child 1", "Root"); | ||
tree.add("Grandchild 1", "Child 1"); | ||
|
||
const child1 = tree.root.children[0]; | ||
expect(child1.children.length).toBe(1); | ||
expect(child1.children[0].value).toBe("Grandchild 1"); | ||
}); | ||
|
||
it("should find an existing node by value", () => { | ||
tree.add("Root"); | ||
tree.add("Child 1", "Root"); | ||
tree.add("Child 2", "Root"); | ||
|
||
const foundNode = tree.findNode(tree.root, "Child 1"); | ||
expect(foundNode).toBeTruthy(); | ||
expect(foundNode.value).toBe("Child 1"); | ||
}); | ||
|
||
it("should return null for a non-existing node", () => { | ||
tree.add("Root"); | ||
expect(tree.findNode(tree.root, "Non-existing")).toBeNull(); | ||
}); | ||
|
||
it("should traverse the tree and execute a callback on each node", () => { | ||
const values = []; | ||
tree.add("Root"); | ||
tree.add("Child 1", "Root"); | ||
tree.add("Child 2", "Root"); | ||
|
||
tree.traverse((node) => values.push(node.value)); | ||
|
||
expect(values).toEqual(["Root", "Child 1", "Child 2"]); | ||
}); | ||
|
||
it("should remove a child node", () => { | ||
tree.add("Root"); | ||
tree.add("Child 1", "Root"); | ||
tree.add("Child 2", "Root"); | ||
|
||
const child1 = tree.root.children[0]; | ||
expect(tree.root.children.length).toBe(2); | ||
|
||
tree.root.removeChild(child1); | ||
expect(tree.root.children.length).toBe(1); | ||
expect(tree.root.children[0].value).toBe("Child 2"); | ||
}); | ||
}); | ||
describe("OrdinalNode", () => { | ||
let node; | ||
|
||
beforeEach(() => { | ||
node = new OrdinalNode("Test Node"); | ||
}); | ||
|
||
it("should initialize a node with the correct value", () => { | ||
expect(node.value).toBe("Test Node"); | ||
expect(node.children.length).toBe(0); | ||
expect(node.parent).toBeNull(); | ||
}); | ||
|
||
it("should add a child node", () => { | ||
const childNode = new OrdinalNode("Child Node"); | ||
node.addChild(childNode); | ||
|
||
expect(node.children.length).toBe(1); | ||
expect(node.children[0].value).toBe("Child Node"); | ||
expect(childNode.parent).toBe(node); | ||
}); | ||
|
||
it("should remove a child node", () => { | ||
const childNode = new OrdinalNode("Child Node"); | ||
node.addChild(childNode); | ||
|
||
expect(node.children.length).toBe(1); | ||
node.removeChild(childNode); | ||
expect(node.children.length).toBe(0); | ||
expect(childNode.parent).toBeNull(); | ||
}); | ||
}); |