implementation of algorithms: 1. compare binary trees, 2. inverse binary tree, 3. reverse linked list

This commit is contained in:
Michał Żarnecki 2024-12-16 20:42:02 +01:00 committed by Brandon Johnson
parent d2fb4603e8
commit 7edf1247c3
11 changed files with 255 additions and 46 deletions

View File

@ -28,14 +28,20 @@
* [Bstree](./DataStructures/BinarySearchTree/BSTree.php)
* [Duplicatekeyexception](./DataStructures/BinarySearchTree/DuplicateKeyException.php)
* CompareBinaryTree
* [CompareBinaryTree](./DataStructures/CompareBinaryTree/CompareBinaryTree.php)
* [Node](./DataStructures/CompareBinaryTree/Node.php)
* [CompareBinaryTree](./DataStructures/CompareBinaryTree.php)
* [BinaryTreeNode](./DataStructures/BinaryTreeNode.php)
* Disjointsets
* [Disjointset](./DataStructures/DisjointSets/DisjointSet.php)
* [Disjointsetnode](./DataStructures/DisjointSets/DisjointSetNode.php)
* [Doublylinkedlist](./DataStructures/DoublyLinkedList.php)
* InvertBinaryTree
* [InvertBinaryTree](./DataStructures/InvertBinaryTree.php)
* [BinaryTree](./DataStructures/BinaryTree.php)
* [Node](./DataStructures/Node.php)
* [Queue](./DataStructures/Queue.php)
* ReverseLinkedList
* [ReverseLinkedList.php](DataStructures/ReverseLinkedList.php)
* [LinkedListItem.php](DataStructures/LinkedListItem.php)
* Segmenttree
* [Segmenttree](./DataStructures/SegmentTree/SegmentTree.php)
* [Segmenttreenode](./DataStructures/SegmentTree/SegmentTreeNode.php)

View File

@ -0,0 +1,40 @@
<?php
class BinaryTree {
private ?BinaryTree $left = null;
private ?BinaryTree $right = null;
private $value;
public function setLeft(?BinaryTree $left)
{
$this->left = $left;
return $this;
}
public function getLeft(): ?BinaryTree
{
return $this->left;
}
public function setRight(?BinaryTree $right)
{
$this->right = $right;
return $this;
}
public function getRight(): ?BinaryTree
{
return $this->right;
}
public function setValue($value)
{
$this->value = $value;
return $this;
}
public function getValue()
{
return $this->value;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace DataStructures;
class BinaryTreeNode
{
public function __construct($value, ?BinaryTreeNode $left = null, BinaryTreeNode $right = null)
{
$this->value = $value;
$this->left = $left;
$this->right = $right;
}
public $value;
public ?BinaryTreeNode $left;
public ?BinaryTreeNode $right;
}

View File

@ -1,5 +1,6 @@
<?php
namespace DataStructures\CompareBinaryTree;
namespace DataStructures;
/**
* Recurrent comparison of binary trees based on comparison of left and right branches
@ -11,11 +12,11 @@ class CompareBinaryTree
{
/**
* compare two binary trees
* @param Node|null $a
* @param Node|null $b
* @param BinaryTreeNode|null $a
* @param BinaryTreeNode|null $b
* @return bool
*/
public function areTreesEqual(?Node $a, ?Node $b): bool
public function areTreesEqual(?BinaryTreeNode $a, ?BinaryTreeNode $b): bool
{
if (! $a && $b || $a && ! $b) {
return false;

View File

@ -1,16 +0,0 @@
<?php
namespace DataStructures\CompareBinaryTree;
class Node
{
public function __construct($value, ?Node $left = null, Node $right = null)
{
$this->value = $value;
$this->left = $left;
$this->right = $right;
}
public $value;
public ?Node $left;
public ?Node $right;
}

View File

@ -0,0 +1,26 @@
<?php
namespace DataStructures;
use BinaryTree;
/**
* Recurrent algorithm to invert binary tree (mirror)
* (https://medium.com/@kvrware/inverting-binary-tree-b0ff3a5cb0df).
*
* @author Michał Żarnecki https://github.com/rzarno
*/
class InvertBinaryTree
{
public function invert(?BinaryTree $b): void
{
if (! $b) {
return;
}
$tmp = $b->getLeft();
$b->setLeft($b->getRight());
$b->setRight($tmp);
$this->invert($b->getLeft());
$this->invert($b->getRight());
}
}

View File

@ -0,0 +1,40 @@
<?php
class LinkedListItem {
private ?LinkedListItem $next = null;
private ?LinkedListItem $prev = null;
private $value;
public function setNext(?LinkedListItem $next)
{
$this->next = $next;
return $this;
}
public function getNext(): ?LinkedListItem
{
return $this->next;
}
public function setPrev(?LinkedListItem $prev)
{
$this->prev = $prev;
return $this;
}
public function getPrev(): ?LinkedListItem
{
return $this->prev;
}
public function setValue($value)
{
$this->value = $value;
return $this;
}
public function getValue()
{
return $this->value;
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* Reverse linked list
* (https://en.wikipedia.org/wiki/Linked_list).
*
* @author Michał Żarnecki https://github.com/rzarno
*/
class ReverseLinkedList
{
public function reverse(LinkedListItem $item): LinkedListItem
{
$next = $item->getNext();
$item->setNext(null);
while (true) {
$item->setPrev($next);
if (! $next) {
return $item;
}
$nextNext = $next->getNext();
$next->setNext($item);
$item = $next;
$next = $nextNext;
}
}
}

View File

@ -3,35 +3,33 @@
namespace DataStructures;
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../../DataStructures/CompareBinaryTree/Node.php';
require_once __DIR__ . '/../../DataStructures/CompareBinaryTree/CompareBinaryTree.php';
require_once __DIR__ . '/../../DataStructures/BinaryTreeNode.php';
require_once __DIR__ . '/../../DataStructures/CompareBinaryTree.php';
use DataStructures\CompareBinaryTree\CompareBinaryTree;
use DataStructures\CompareBinaryTree\Node;
use PHPUnit\Framework\TestCase;
class CompareBinaryTreeTest extends TestCase
{
public function testBinaryTreesAreEqualWhenAreEqualInReality()
{
$tree1 = new Node(
$tree1 = new BinaryTreeNode(
'A',
new Node(
new BinaryTreeNode(
'B',
new Node(
new BinaryTreeNode(
'D'
),
new Node(
new BinaryTreeNode(
'E',
null,
new Node(
new BinaryTreeNode(
'F'
)
)
),
new Node(
new BinaryTreeNode(
'C',
new Node('G')
new BinaryTreeNode('G')
)
);
@ -44,43 +42,43 @@ class CompareBinaryTreeTest extends TestCase
public function testBinaryTreesAreNotEqualWhenAreNotEqualInReality()
{
$tree1 = new Node(
$tree1 = new BinaryTreeNode(
'A',
new Node(
new BinaryTreeNode(
'B',
new Node(
new BinaryTreeNode(
'F'
),
new Node(
new BinaryTreeNode(
'E',
null,
new Node(
new BinaryTreeNode(
'D'
)
)
),
new Node(
new BinaryTreeNode(
'C',
new Node('G')
new BinaryTreeNode('G')
)
);
$tree2 = new Node(
$tree2 = new BinaryTreeNode(
'A',
new Node(
new BinaryTreeNode(
'B',
new Node(
new BinaryTreeNode(
'F'
),
new Node(
new BinaryTreeNode(
'E',
null,
new Node(
new BinaryTreeNode(
'D'
)
)
),
new Node(
new BinaryTreeNode(
'C'
)
);

View File

@ -0,0 +1,36 @@
<?php
namespace DataStructures;
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../../DataStructures/BinaryTree.php';
require_once __DIR__ . '/../../DataStructures/InvertBinaryTree.php';
use BinaryTree;
use PHPUnit\Framework\TestCase;
class InvertBinaryTreeTest extends TestCase
{
public function testInvertBinaryTree()
{
$b = (new BinaryTree())->setValue(1);
$bl = (new BinaryTree())->setValue(3);
$b->setLeft($bl);
$br = (new BinaryTree())->setValue(2);
$b->setRight($br);
$br->setLeft((new BinaryTree())->setValue(4));
$br->setRight((new BinaryTree())->setValue(5));
$expected = (new BinaryTree())->setValue(1);
$expectedBr = (new BinaryTree())->setValue(3);
$expected->setRight($expectedBr);
$expectedBl = (new BinaryTree())->setValue(2);
$expected->setLeft($expectedBl);
$expectedBl->setRight((new BinaryTree())->setValue(4));
$expectedBl->setLeft((new BinaryTree())->setValue(5));
(new InvertBinaryTree())->invert($b);
$this->assertEquals($expected, $b);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace DataStructures;
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../../DataStructures/LinkedListItem.php';
require_once __DIR__ . '/../../DataStructures/ReverseLinkedList.php';
use LinkedListItem;
use ReverseLinkedList;
use PHPUnit\Framework\TestCase;
class ReverseLinkedListTest extends TestCase
{
public function testReverseLinkedList()
{
$list = [1,2,3,4,5];
$firstItem = (new LinkedListItem())->setValue(0);
$prevItem = $firstItem;
foreach ($list as $value) {
$item = new LinkedListItem();
$item->setValue($value);
$item->setPrev($prevItem);
$prevItem->setNext($item);
$prevItem = $item;
}
$newFirstItem = (new ReverseLinkedList())->reverse($firstItem);
do {
$this->assertEquals($newFirstItem->getValue(), array_pop($list));
} while ($newFirstItem = $newFirstItem->getNext());
}
}