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:
Ramy 2024-10-15 22:43:04 +02:00 committed by GitHub
parent 9e0964a1bb
commit ea4d3b0fdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 145 additions and 4 deletions

View File

@ -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);
}
}
}

View File

@ -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'
);
}
}