mirror of
https://github.com/TheAlgorithms/PHP.git
synced 2025-01-29 04:57:33 +01:00
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 <bbj1979@gmail.com> * Update DataStructures/DisjointSets/DisjointSetNode.php Co-authored-by: Brandon Johnson <bbj1979@gmail.com> * Update DataStructures/DisjointSets/DisjointSetNode.php Co-authored-by: Brandon Johnson <bbj1979@gmail.com> * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson <bbj1979@gmail.com> * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson <bbj1979@gmail.com> * Update tests/DataStructures/DisjointSetTest.php Co-authored-by: Brandon Johnson <bbj1979@gmail.com> * 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 <bbj1979@gmail.com> * Implemented AVL Tree Data Structure. Added serialization/deserialization feature. Added corresponding unit test. --------- Co-authored-by: Brandon Johnson <bbj1979@gmail.com> Co-authored-by: Ramy-Badr-Ahmed <Ramy-Badr-Ahmed@users.noreply.github.com>
This commit is contained in:
parent
9e0964a1bb
commit
ea4d3b0fdd
@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request: #163
|
||||
* https://github.com/TheAlgorithms/PHP/pull/163
|
||||
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
|
||||
* in Pull Request #163: https://github.com/TheAlgorithms/PHP/pull/163
|
||||
* and #173: https://github.com/TheAlgorithms/PHP/pull/173
|
||||
*
|
||||
* Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request addressing bugs/corrections to this file.
|
||||
* Thank you!
|
||||
@ -311,4 +312,81 @@ class AVLTree
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the segment tree into a JSON string.
|
||||
*
|
||||
* @return string The serialized AVL Tree as a JSON string.
|
||||
*/
|
||||
public function serialize(): string
|
||||
{
|
||||
return json_encode($this->serializeTree($this->root));
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively serializes the AVL Tree.
|
||||
*
|
||||
* @param AVLTreeNode|null $node
|
||||
* @return array
|
||||
*/
|
||||
private function serializeTree(?AVLTreeNode $node): array
|
||||
{
|
||||
if ($node === null) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
'key' => $node->key,
|
||||
'value' => $node->value,
|
||||
'left' => $this->serializeTree($node->left),
|
||||
'right' => $this->serializeTree($node->right),
|
||||
'height' => $node->height,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a JSON string into an AVL Tree object
|
||||
*
|
||||
* @param string $data The JSON representation of an AVL Tree to deserialize.
|
||||
*/
|
||||
public function deserialize(string $data): void
|
||||
{
|
||||
$this->root = $this->deserializeTree(json_decode($data, true));
|
||||
$this->counter = 0;
|
||||
$this->updateNodeCount($this->root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively deserializes an AVL Tree from an array representation.
|
||||
*
|
||||
* @param array $data The serialized data for the node.
|
||||
* @return AVLTreeNode|null The root node of the deserialized tree.
|
||||
*/
|
||||
private function deserializeTree(array $data): ?AVLTreeNode
|
||||
{
|
||||
if (empty($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$node = new AVLTreeNode($data['key'], $data['value']);
|
||||
$node->height = $data['height'];
|
||||
|
||||
$node->left = $this->deserializeTree($data['left']);
|
||||
$node->right = $this->deserializeTree($data['right']);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the deserialized tree size.
|
||||
*
|
||||
* @param AVLTreeNode|null $node The root node of the deserialized tree.
|
||||
*/
|
||||
private function updateNodeCount(?AVLTreeNode $node): void
|
||||
{
|
||||
if ($node !== null) {
|
||||
$this->counter++;
|
||||
$this->updateNodeCount($node->left);
|
||||
$this->updateNodeCount($node->right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed) in Pull Request: #163
|
||||
* https://github.com/TheAlgorithms/PHP/pull/163
|
||||
* Created by: Ramy-Badr-Ahmed (https://github.com/Ramy-Badr-Ahmed)
|
||||
* in Pull Request #163: https://github.com/TheAlgorithms/PHP/pull/163
|
||||
* and #173: https://github.com/TheAlgorithms/PHP/pull/173
|
||||
*
|
||||
* Please mention me (@Ramy-Badr-Ahmed) in any issue or pull request addressing bugs/corrections to this file.
|
||||
* Thank you!
|
||||
@ -37,6 +38,9 @@ class AVLTreeTest extends TestCase
|
||||
$this->tree->insert(15, 'Value 15');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the insert and search operations in the AVLTree.
|
||||
*/
|
||||
public function testInsertAndSearch(): void
|
||||
{
|
||||
$this->populateTree();
|
||||
@ -47,6 +51,10 @@ class AVLTreeTest extends TestCase
|
||||
$this->assertNull($this->tree->search(25), 'Value for non-existent key 25 should be null');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the deletion of nodes and ensures the AVLTree maintains
|
||||
* its integrity after deletions.
|
||||
*/
|
||||
public function testDelete(): void
|
||||
{
|
||||
$this->populateTree();
|
||||
@ -167,6 +175,9 @@ class AVLTreeTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the insertion and deletion of a large number of nodes.
|
||||
*/
|
||||
public function testLargeTree(): void
|
||||
{
|
||||
// Inserting a large number of nodes
|
||||
@ -186,6 +197,9 @@ class AVLTreeTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the AVLTree remains balanced after insertions.
|
||||
*/
|
||||
public function testBalance(): void
|
||||
{
|
||||
$this->populateTree();
|
||||
@ -300,4 +314,53 @@ class AVLTreeTest extends TestCase
|
||||
$this->tree = new AVLTree();
|
||||
$this->assertEquals(0, $this->tree->size(), 'Size should be 0 for an empty tree');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test serialization and deserialization
|
||||
*/
|
||||
public function testAVLTreeSerialization(): void
|
||||
{
|
||||
$avlTree = new AVLTree();
|
||||
|
||||
$avlTree->insert(100, 'Value 100');
|
||||
$avlTree->insert(200, 'Value 200');
|
||||
$avlTree->insert(50, 'Value 50');
|
||||
$avlTree->insert(150, 'Value 150');
|
||||
$avlTree->insert(350, 'Value 350');
|
||||
$avlTree->insert(40, 'Value 40');
|
||||
$avlTree->insert(90, 'Value 90');
|
||||
|
||||
$avlTreeRoot = $avlTree->getRoot();
|
||||
$serializedAVLTree = $avlTree->serialize();
|
||||
|
||||
$deserializedTree = new AVLTree();
|
||||
$deserializedTree->deserialize($serializedAVLTree);
|
||||
|
||||
$deserializedTreeRoot = $deserializedTree->getRoot();
|
||||
|
||||
$this->assertEquals($deserializedTreeRoot->key, $avlTreeRoot->key, 'The two roots key should match');
|
||||
$this->assertEquals($deserializedTreeRoot->value, $avlTreeRoot->value, 'The two roots value should match');
|
||||
$this->assertEquals(
|
||||
$deserializedTreeRoot->left->key,
|
||||
$avlTreeRoot->left->key,
|
||||
'Left child of the two roots should match'
|
||||
);
|
||||
$this->assertEquals(
|
||||
$deserializedTreeRoot->right->key,
|
||||
$avlTreeRoot->right->key,
|
||||
'Left child of the two roots should match'
|
||||
);
|
||||
$this->assertEquals(
|
||||
$deserializedTreeRoot->height,
|
||||
$avlTreeRoot->height,
|
||||
'The two trees should match in height'
|
||||
);
|
||||
$this->assertEquals($deserializedTree->size(), $avlTree->size(), 'The two trees should match in size');
|
||||
|
||||
$this->assertSame(
|
||||
$deserializedTree->inOrderTraversal(),
|
||||
$avlTree->inOrderTraversal(),
|
||||
'Tree structure was not retained'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user