Skip to content

Commit

Permalink
binary search tree logic
Browse files Browse the repository at this point in the history
  • Loading branch information
terrencejihoonjung committed Sep 14, 2024
1 parent 8eb1316 commit f6eb523
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/AppRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import DoublyLinkedList from "./pages/DoublyLinkedList";
import HashTable from "./pages/HashTable";
import Queue from "./pages/Queue";
import Stack from "./pages/Stack";
import BinarySearchTree from "./pages/BinarySearchTree";

function AppRouter() {
return (
Expand All @@ -19,6 +20,7 @@ function AppRouter() {
<Route path="hash-table" element={<HashTable />} />
<Route path="stack" element={<Stack />} />
<Route path="queue" element={<Queue />} />
<Route path="binary-search-tree" element={<BinarySearchTree />} />
</Route>
</Routes>
);
Expand Down
135 changes: 135 additions & 0 deletions src/components/DSPlaygrounds/BinarySearchTreePG.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useState } from "react";
import { PlaygroundProps } from "../../entities";
import { Link } from "react-router-dom";
import PencilIcon from "../Icons/PencilIcon";
import map from "../../data/data-structures";

interface TreeNode {
value: number;
left: TreeNode | null;
right: TreeNode | null;
}

function BinarySearchTreePG({ className }: PlaygroundProps) {
const ds = map.get("binary-search-tree")!;
const [root, setRoot] = useState<TreeNode | null>(null);
const [inputValue, setInputValue] = useState("");
const [errorMessage, setErrorMessage] = useState("");

const insert = (node: TreeNode | null, value: number): TreeNode => {
if (node === null) {
return { value, left: null, right: null };
}

if (value < node.value) {
return { ...node, left: insert(node.left, value) };
} else if (value > node.value) {
return { ...node, right: insert(node.right, value) };
}

return node;
};

const handleInsert = () => {
const value = parseInt(inputValue);
if (isNaN(value)) {
setErrorMessage("Please enter a valid number");
return;
}

setRoot((prevRoot) => insert(prevRoot, value));
setInputValue("");
setErrorMessage("");
};

const findMin = (node: TreeNode): TreeNode => {
let curr = node;
while (curr.left !== null) {
curr = curr.left;
}
return curr;
};

const deleteNode = (
node: TreeNode | null,
value: number
): TreeNode | null => {
if (node === null) return null;

if (value < node.value) {
return { ...node, left: deleteNode(node.left, value) };
} else if (value > node.value) {
return { ...node, right: deleteNode(node.right, value) };
}

// Node to delete found
else {
// Case 1 - Leaf Node
if (node.left === null && node.right === null) {
return null;
}

// Case 2 - Node with 1 child
if (node.left === null) {
return node.right;
}
if (node.right === null) {
return node.left;
}

// Case 3 - Node with 2 children
const minNode = findMin(node.right);
return {
...node,
value: minNode.value,
right: deleteNode(node.right, minNode.value),
};
}
};

const handleDelete = () => {
const value = parseInt(inputValue);
if (isNaN(value)) {
setErrorMessage("Please enter a valid number");
return;
}
setRoot((prevRoot) => deleteNode(prevRoot, value));
setInputValue("");
setErrorMessage("");
};

return (
<div className={`flex flex-col w-full grow space-y-4 ${className}`}>
<div className="flex justify-between items-center">
<div className="flex items-center space-x-2">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
className="input input-bordered"
placeholder="Enter a number"
/>
<button onClick={handleInsert} className="btn btn-outline">
Insert
</button>
<button onClick={handleDelete} className="btn btn-outline">
Delete
</button>
</div>
<Link to={ds.notesUrl} className="btn btn-outline">
<PencilIcon /> <p>Notes</p>
</Link>
</div>

{/* Visualization Window - To be implemented */}
<div className="relative p-4 grow w-full border border-black rounded-md">
{/* Tree visualization will go here */}
</div>

{/* Error Messages */}
{errorMessage && <div className="text-red-500 mb-4">{errorMessage}</div>}
</div>
);
}

export default BinarySearchTreePG;
31 changes: 22 additions & 9 deletions src/data/data-structures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const dataStructures: DataStructureKV[] = [
"dynamic-array",
{
name: "Dynamic Array",
description: "Resizable arrays with dynamic capacity.",
description: "Resizable arrays with dynamic capacity",
icon: "🪟",
category: "Arrays/Strings",
difficulty: "Beginner",
Expand All @@ -16,7 +16,7 @@ export const dataStructures: DataStructureKV[] = [
"singly-linked-list",
{
name: "Singly Linked List",
description: "Linear collection with nodes linked in sequence.",
description: "Linear collection with nodes linked in sequence",
icon: "🔜",
category: "Linked Lists",
difficulty: "Beginner",
Expand All @@ -27,7 +27,7 @@ export const dataStructures: DataStructureKV[] = [
"doubly-linked-list",
{
name: "Doubly Linked List",
description: "Nodes linked bi-directionally for efficient traversal.",
description: "Nodes linked bi-directionally for efficient traversal",
icon: "🔛",
category: "Linked Lists",
difficulty: "Beginner",
Expand All @@ -38,7 +38,7 @@ export const dataStructures: DataStructureKV[] = [
"hash-table",
{
name: "Hash Table",
description: "Key-value pairs for efficient data retrieval.",
description: "Key-value pairs for efficient data retrieval",
icon: "🧮",
category: "Hashing",
difficulty: "Beginner",
Expand Down Expand Up @@ -70,12 +70,25 @@ export const dataStructures: DataStructureKV[] = [
},
],
[
"binary-search",
"binary-search-tree",
{
name: "Binary Search",
description: "",
icon: "⏱️",
category: "",
name: "Binary Search Tree",
description:
"A binary tree where left child < parent < right child for all nodes",
icon: "🌲",
category: "Tree",
difficulty: "Intermediate",
notesUrl: "",
},
],
[
"graph",
{
name: "Graph",
description:
"A non-linear data structure consisting of vertices (or nodes) connected by edges",
icon: "🕸️",
category: "Graph",
difficulty: "Intermediate",
notesUrl: "",
},
Expand Down
Empty file removed src/pages/BinarySearch.tsx
Empty file.
21 changes: 21 additions & 0 deletions src/pages/BinarySearchTree.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import map from "../data/data-structures";
import Heading from "../components/Heading";
import BinarySearchTreePG from "../components/DSPlaygrounds/BinarySearchTreePG";

function BinarySearchTree() {
const binarySearchTree = map.get("binary-search-tree")!;

return (
<div className="w-full h-screen p-8">
<div className="w-3/5 mx-auto h-full flex flex-col">
{/* Heading */}
<Heading ds={binarySearchTree} className="mb-8" />

{/* Playground */}
<BinarySearchTreePG />
</div>
</div>
);
}

export default BinarySearchTree;

0 comments on commit f6eb523

Please sign in to comment.