From cb2bbf948cc35955da79577e242212487eb9452c Mon Sep 17 00:00:00 2001 From: Ramy Date: Tue, 15 Oct 2024 22:55:42 +0200 Subject: [PATCH] Added Extra Tests for Splay Tree Operations (#171) * Added Disjoint Sets Data structure * Moved DisjointSetTest.php to tests/DataStructures * Update DataStructures/DisjointSets/DisjointSet.php Co-authored-by: Brandon Johnson * Update DataStructures/DisjointSets/DisjointSetNode.php Co-authored-by: Brandon Johnson * Update DataStructures/DisjointSets/DisjointSetNode.php Co-authored-by: Brandon Johnson * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson * Considered PHPCS remarks. Unit Testing is now working. * Remove data type mixed. Considered annotations for php7.4. * Remove data type mixed. Considered annotations for php7.4. * updating DIRECTORY.md * Implemented Trie DataStructure * Added Trie to DIRECTORY.md * updating DIRECTORY.md * Implemented AVLTree DataStructure * updating DIRECTORY.md * Implemented AVLTree DataStructure * Implemented SegmentTreeNode.php * Implementing SegmentTree * Implementing SegmentTree with updateTree * Implementing SegmentTree with rangeUpdateTree * Implementing SegmentTree with query and queryTree * Added serializing and deserializing of the SegmentTree * Adding unit tests SegmentTree implementation * Added unit tests for SegmentTree updates and range updates * considering PHPCS for Added unit tests for SegmentTree updates and range updates * Added unit tests for SegmentTree serialization/deserialization and array updates reflections * Added unit tests for SegmentTree Edge Cases * Added unit tests for SegmentTree Exceptions (OutOfBoundsException, InvalidArgumentException) * Added SegmentTree to DIRECTORY.md * Implemented Segment Tree Data Structure * updating DIRECTORY.md * Added some comments to my files in: #160, #162, #163, #166. Implemented Segment Tree Data Structure. * Added some comments to my files in: #160, #162, #163, #166. Implemented Segment Tree Data Structure. * Added comments time complexity for query(), update() and buildTree() * Implemented Splay Tree Data Structure * Update tests/DataStructures/SplayTreeTest.php Co-authored-by: Brandon Johnson * Implemented Splay Tree Data Structure. Added counter test for deletion. * Implemented Splay Tree Data Structure. Added counter test for multiple deletions. * Implemented Splay Tree Data Structure. Added counter test for multiple deletions. * Implemented Splay Tree Data Structure. Added abstract setRoot() declaration to the SplayTreeRotations.php * Implemented Splay Tree Data Structure. Fix for array_rand for non-array result. Rewriting. * Implemented Splay Tree Data Structure. Fix for multiple deletion test. * Implemented Splay Tree Data Structure. Added test for large splay tree operations. --------- Co-authored-by: Brandon Johnson Co-authored-by: Ramy-Badr-Ahmed --- DataStructures/SplayTree/SplayTree.php | 2 +- .../SplayTree/SplayTreeRotations.php | 1 + tests/DataStructures/SplayTreeTest.php | 71 +++++++++++++++++-- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/DataStructures/SplayTree/SplayTree.php b/DataStructures/SplayTree/SplayTree.php index ac8e80b..c14b64a 100644 --- a/DataStructures/SplayTree/SplayTree.php +++ b/DataStructures/SplayTree/SplayTree.php @@ -44,7 +44,7 @@ public function getRoot(): ?SplayTreeNode * Set the root node of the Splay Tree. * @param SplayTreeNode $node */ - public function setRoot(SplayTreeNode $node): void + protected function setRoot(SplayTreeNode $node): void { $this->root = $node; } diff --git a/DataStructures/SplayTree/SplayTreeRotations.php b/DataStructures/SplayTree/SplayTreeRotations.php index ec4ad36..3375caa 100644 --- a/DataStructures/SplayTree/SplayTreeRotations.php +++ b/DataStructures/SplayTree/SplayTreeRotations.php @@ -13,6 +13,7 @@ abstract class SplayTreeRotations { abstract protected function splay(?SplayTreeNode $node, int $key): ?SplayTreeNode; + abstract protected function setRoot(SplayTreeNode $node): void; /** * Zig rotation (single right rotation). diff --git a/tests/DataStructures/SplayTreeTest.php b/tests/DataStructures/SplayTreeTest.php index 9c33ffa..8234820 100644 --- a/tests/DataStructures/SplayTreeTest.php +++ b/tests/DataStructures/SplayTreeTest.php @@ -1,8 +1,9 @@ assertNull( $node->parent, - "The last visited node must have become the new root with has no parent. Failed to splay correctly." + "The last visited node must have become the new root which has no parent. Failed to splay correctly." ); } @@ -390,7 +391,7 @@ public function testUpdateNonExistingKey() ); $this->assertNull( $node->parent, - "The last visited node must have become the new root with has no parent. Failed to splay correctly." + "The last visited node must have become the new root which has no parent. Failed to splay correctly." ); } @@ -401,10 +402,18 @@ public function testDeleteExistingKey() { $this->populateTree(); + $nodesNumber = $this->tree->size(); $node = $this->tree->delete(22); - $isFound = $this->tree->isFound(22); + $isFound = $this->tree->isFound(22); $this->assertFalse($isFound, "Node with key 22 was not deleted."); + + $this->assertEquals( + $nodesNumber - 1, + $this->tree->size(), + "After deletion, total nodes count was not updated correctly." + ); + $this->assertEquals( 20, $node->key, @@ -441,6 +450,36 @@ public function testMergeAfterDeleteExistingKey() ); } + /** + * Tests deletion of multiple nodes and checks if the tree size is updated. + */ + public function testDeleteMultipleKeys() + { + $arrayData = [200 => "Value 200", 150 => "Value 150", 170 => "Value 170", + 250 => "Value 250", 300 => "Value 300", 360 => "Value 360", 230 => "Value 230", + 240 => "Value 240", 220 => "Value 220", 50 => "Value 50", 28 => "Value 28", + 164 => "Value 164", 321 => "Value 321", 40 => "Value 40" + ]; + + $splayTree = new SplayTree($arrayData); + $treeSize = $splayTree->size(); + + $nodesToDelete = [150, 300, 50, 240, 170]; + $expectedSize = $treeSize - count($nodesToDelete); + + foreach ($nodesToDelete as $key) { + $splayTree->delete($key); + $isFound = $this->tree->isFound($key); + $this->assertFalse($isFound, "Node with key $key was not deleted."); + } + + $this->assertEquals( + $expectedSize, + $splayTree->size(), + "After deletion, total nodes count was not updated correctly." + ); + } + /** * Ensures that attempting to delete a non-existing key throws an exception and keeps the tree intact. */ @@ -478,6 +517,28 @@ public function testOperationsOnEmptyTree() $this->assertNull($rootNode4, "Deleting a key in an empty tree should return null."); } + /** + * Test insert, search, delete on large trees + */ + public function testLargeTree(): void + { + // Inserting a large number of nodes + for ($i = 1; $i <= 1000; $i++) { + $this->tree->insert($i, "Value $i"); + } + + // Verify that all inserted nodes can be searched + for ($i = 1; $i <= 1000; $i++) { + $this->assertEquals("Value $i", $this->tree->search($i)->value, "Value for key $i should be 'Value $i'"); + } + + // Verify that all inserted nodes can be deleted + for ($i = 1; $i <= 5; $i++) { + $this->tree->delete($i); + $this->assertFalse($this->tree->isFound($i), "Node was not deleted correctly"); + } + } + // ------------- Test 6 Rotation types of the Splay Tree -------------