Skip to content

Commit ea4d3b0

Browse files
Enhanced AVL Tree Data Structure with (de-)serialization Feature (#173)
* Added Disjoint Sets Data structure * Moved DisjointSetTest.php to tests/DataStructures * Update DataStructures/DisjointSets/DisjointSet.php Co-authored-by: Brandon Johnson <[email protected]> * Update DataStructures/DisjointSets/DisjointSetNode.php Co-authored-by: Brandon Johnson <[email protected]> * Update DataStructures/DisjointSets/DisjointSetNode.php Co-authored-by: Brandon Johnson <[email protected]> * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson <[email protected]> * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson <[email protected]> * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson <[email protected]> * 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 <[email protected]> * Implemented AVL Tree Data Structure. Added serialization/deserialization feature. Added corresponding unit test. --------- Co-authored-by: Brandon Johnson <[email protected]> Co-authored-by: Ramy-Badr-Ahmed <[email protected]>
1 parent 9e0964a commit ea4d3b0

File tree

2 files changed

+145
-4
lines changed

2 files changed

+145
-4
lines changed

DataStructures/AVLTree/AVLTree.php

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<?php
22

33
/*
4-
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request: #163
5-
* https://github.com/TheAlgorithms/PHP/pull/163
4+
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
5+
* in Pull Request #163: https://github.com/TheAlgorithms/PHP/pull/163
6+
* and #173: https://github.com/TheAlgorithms/PHP/pull/173
67
*
78
* Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request addressing bugs/corrections to this file.
89
* Thank you!
@@ -311,4 +312,81 @@ private function getMinNode(AVLTreeNode $node): AVLTreeNode
311312
}
312313
return $node;
313314
}
315+
316+
/**
317+
* Serializes the segment tree into a JSON string.
318+
*
319+
* @return string The serialized AVL Tree as a JSON string.
320+
*/
321+
public function serialize(): string
322+
{
323+
return json_encode($this->serializeTree($this->root));
324+
}
325+
326+
/**
327+
* Recursively serializes the AVL Tree.
328+
*
329+
* @param AVLTreeNode|null $node
330+
* @return array
331+
*/
332+
private function serializeTree(?AVLTreeNode $node): array
333+
{
334+
if ($node === null) {
335+
return [];
336+
}
337+
return [
338+
'key' => $node->key,
339+
'value' => $node->value,
340+
'left' => $this->serializeTree($node->left),
341+
'right' => $this->serializeTree($node->right),
342+
'height' => $node->height,
343+
];
344+
}
345+
346+
/**
347+
* Deserializes a JSON string into an AVL Tree object
348+
*
349+
* @param string $data The JSON representation of an AVL Tree to deserialize.
350+
*/
351+
public function deserialize(string $data): void
352+
{
353+
$this->root = $this->deserializeTree(json_decode($data, true));
354+
$this->counter = 0;
355+
$this->updateNodeCount($this->root);
356+
}
357+
358+
/**
359+
* Recursively deserializes an AVL Tree from an array representation.
360+
*
361+
* @param array $data The serialized data for the node.
362+
* @return AVLTreeNode|null The root node of the deserialized tree.
363+
*/
364+
private function deserializeTree(array $data): ?AVLTreeNode
365+
{
366+
if (empty($data)) {
367+
return null;
368+
}
369+
370+
$node = new AVLTreeNode($data['key'], $data['value']);
371+
$node->height = $data['height'];
372+
373+
$node->left = $this->deserializeTree($data['left']);
374+
$node->right = $this->deserializeTree($data['right']);
375+
376+
return $node;
377+
}
378+
379+
/**
380+
* Updates the deserialized tree size.
381+
*
382+
* @param AVLTreeNode|null $node The root node of the deserialized tree.
383+
*/
384+
private function updateNodeCount(?AVLTreeNode $node): void
385+
{
386+
if ($node !== null) {
387+
$this->counter++;
388+
$this->updateNodeCount($node->left);
389+
$this->updateNodeCount($node->right);
390+
}
391+
}
314392
}

tests/DataStructures/AVLTreeTest.php

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<?php
22

33
/*
4-
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request: #163
5-
* https://github.com/TheAlgorithms/PHP/pull/163
4+
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
5+
* in Pull Request #163: https://github.com/TheAlgorithms/PHP/pull/163
6+
* and #173: https://github.com/TheAlgorithms/PHP/pull/173
67
*
78
* Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request addressing bugs/corrections to this file.
89
* Thank you!
@@ -37,6 +38,9 @@ private function populateTree(): void
3738
$this->tree->insert(15, 'Value 15');
3839
}
3940

41+
/**
42+
* Tests the insert and search operations in the AVLTree.
43+
*/
4044
public function testInsertAndSearch(): void
4145
{
4246
$this->populateTree();
@@ -47,6 +51,10 @@ public function testInsertAndSearch(): void
4751
$this->assertNull($this->tree->search(25), 'Value for non-existent key 25 should be null');
4852
}
4953

54+
/**
55+
* Tests the deletion of nodes and ensures the AVLTree maintains
56+
* its integrity after deletions.
57+
*/
5058
public function testDelete(): void
5159
{
5260
$this->populateTree();
@@ -167,6 +175,9 @@ public function testInsertDuplicateKeys(): void
167175
);
168176
}
169177

178+
/**
179+
* Tests the insertion and deletion of a large number of nodes.
180+
*/
170181
public function testLargeTree(): void
171182
{
172183
// Inserting a large number of nodes
@@ -186,6 +197,9 @@ public function testLargeTree(): void
186197
}
187198
}
188199

200+
/**
201+
* Tests whether the AVLTree remains balanced after insertions.
202+
*/
189203
public function testBalance(): void
190204
{
191205
$this->populateTree();
@@ -300,4 +314,53 @@ public function testSizeOnEmptyTree(): void
300314
$this->tree = new AVLTree();
301315
$this->assertEquals(0, $this->tree->size(), 'Size should be 0 for an empty tree');
302316
}
317+
318+
/**
319+
* Test serialization and deserialization
320+
*/
321+
public function testAVLTreeSerialization(): void
322+
{
323+
$avlTree = new AVLTree();
324+
325+
$avlTree->insert(100, 'Value 100');
326+
$avlTree->insert(200, 'Value 200');
327+
$avlTree->insert(50, 'Value 50');
328+
$avlTree->insert(150, 'Value 150');
329+
$avlTree->insert(350, 'Value 350');
330+
$avlTree->insert(40, 'Value 40');
331+
$avlTree->insert(90, 'Value 90');
332+
333+
$avlTreeRoot = $avlTree->getRoot();
334+
$serializedAVLTree = $avlTree->serialize();
335+
336+
$deserializedTree = new AVLTree();
337+
$deserializedTree->deserialize($serializedAVLTree);
338+
339+
$deserializedTreeRoot = $deserializedTree->getRoot();
340+
341+
$this->assertEquals($deserializedTreeRoot->key, $avlTreeRoot->key, 'The two roots key should match');
342+
$this->assertEquals($deserializedTreeRoot->value, $avlTreeRoot->value, 'The two roots value should match');
343+
$this->assertEquals(
344+
$deserializedTreeRoot->left->key,
345+
$avlTreeRoot->left->key,
346+
'Left child of the two roots should match'
347+
);
348+
$this->assertEquals(
349+
$deserializedTreeRoot->right->key,
350+
$avlTreeRoot->right->key,
351+
'Left child of the two roots should match'
352+
);
353+
$this->assertEquals(
354+
$deserializedTreeRoot->height,
355+
$avlTreeRoot->height,
356+
'The two trees should match in height'
357+
);
358+
$this->assertEquals($deserializedTree->size(), $avlTree->size(), 'The two trees should match in size');
359+
360+
$this->assertSame(
361+
$deserializedTree->inOrderTraversal(),
362+
$avlTree->inOrderTraversal(),
363+
'Tree structure was not retained'
364+
);
365+
}
303366
}

0 commit comments

Comments
 (0)