Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implementation of algorithms: Dijkstra's, compare binary trees, invert binary tree, reverse linked list #181

Merged
merged 7 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,21 @@
* [Bstnode](./DataStructures/BinarySearchTree/BSTNode.php)
* [Bstree](./DataStructures/BinarySearchTree/BSTree.php)
* [Duplicatekeyexception](./DataStructures/BinarySearchTree/DuplicateKeyException.php)
* CompareBinaryTree
* [CompareBinaryTree](./DataStructures/CompareBinaryTree/CompareBinaryTree.php)
* [BinaryTreeNode](./DataStructures/CompareBinaryTree/BinaryTreeNode.php)
* Disjointsets
* [Disjointset](./DataStructures/DisjointSets/DisjointSet.php)
* [Disjointsetnode](./DataStructures/DisjointSets/DisjointSetNode.php)
* [Doublylinkedlist](./DataStructures/DoublyLinkedList.php)
* InvertBinaryTree
* [InvertBinaryTree](./DataStructures/InvertBinaryTree/InvertBinaryTree.php)
* [BinaryTree](./DataStructures/InvertBinaryTree/BinaryTree.php)
* [Node](./DataStructures/Node.php)
* [Queue](./DataStructures/Queue.php)
* ReverseLinkedList
* [ReverseLinkedList.php](DataStructures/ReverseLinkedList/ReverseLinkedList.php)
* [LinkedListItem.php](DataStructures/ReverseLinkedList/LinkedListItem.php)
* Segmenttree
* [Segmenttree](./DataStructures/SegmentTree/SegmentTree.php)
* [Segmenttreenode](./DataStructures/SegmentTree/SegmentTreeNode.php)
Expand All @@ -50,6 +59,8 @@
* [Bellmanford](./Graphs/BellmanFord.php)
* [Breadthfirstsearch](./Graphs/BreadthFirstSearch.php)
* [Depthfirstsearch](./Graphs/DepthFirstSearch.php)
* [Dijkstra's](./Graphs/Dijkstras.php)
* [Edge.php](Graphs/Edge.php)

## Maths
* [Absolutemax](./Maths/AbsoluteMax.php)
Expand Down Expand Up @@ -85,6 +96,7 @@
* [Problem7](./Maths/ProjectEuler/Problem7.php)
* [Problem8](./Maths/ProjectEuler/Problem8.php)
* [Problem9](./Maths/ProjectEuler/Problem9.php)
* [Eratosthenessieve](./Maths/EratosthenesSieve.php)

## Searches
* [Binarysearch](./Searches/BinarySearch.php)
Expand Down Expand Up @@ -155,6 +167,7 @@
* [Eratosthenessievetest](./tests/Maths/EratosthenesSieveTest.php)
* [Mathstest](./tests/Maths/MathsTest.php)
* [Projecteulertest](./tests/Maths/ProjectEulerTest.php)
* [Eratosthenessievetest](./tests/Maths/EratosthenesSieveTest.php)
* Searches
* [Searchestest](./tests/Searches/SearchesTest.php)
* Sorting
Expand Down
17 changes: 17 additions & 0 deletions DataStructures/CompareBinaryTree/BinaryTreeNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace DataStructures\CompareBinaryTree;

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;
}
35 changes: 35 additions & 0 deletions DataStructures/CompareBinaryTree/CompareBinaryTree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace DataStructures\CompareBinaryTree;

/**
* Recurrent comparison of binary trees based on comparison of left and right branches
* (https://en.wikipedia.org/wiki/Binary_tree).
*
* @author Michał Żarnecki https://github.com/rzarno
*/
class CompareBinaryTree
{
/**
* compare two binary trees
* @param BinaryTreeNode|null $a
* @param BinaryTreeNode|null $b
* @return bool
*/
public function areTreesEqual(?BinaryTreeNode $a, ?BinaryTreeNode $b): bool
{
if (! $a && $b || $a && ! $b) {
return false;
}

if (! $a && ! $b) {
return true;
}

if ($a->value !== $b->value) {
return false;
}
return $this->areTreesEqual($a->left, $b->left)
&& $this->areTreesEqual($a->right, $b->right);
}
}
43 changes: 43 additions & 0 deletions DataStructures/InvertBinaryTree/BinaryTree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace DataStructures\InvertBinaryTree;

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;
}
}
24 changes: 24 additions & 0 deletions DataStructures/InvertBinaryTree/InvertBinaryTree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace DataStructures\InvertBinaryTree;

/**
* 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());
}
}
43 changes: 43 additions & 0 deletions DataStructures/ReverseLinkedList/LinkedListItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace DataStructures\ReverseLinkedList;

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;
}
}
28 changes: 28 additions & 0 deletions DataStructures/ReverseLinkedList/ReverseLinkedList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace DataStructures\ReverseLinkedList;

/**
* 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;
}
}
}
21 changes: 8 additions & 13 deletions Graphs/BellmanFord.php
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
<?php

class Edge
{
public $start;
public $end;
public int $weight;
}

/**
* The Bellman–Ford algorithm is an algorithm that computes shortest paths from a single source vertex to all of the
* other vertices in a weighted digraph.
* (https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm).
*
* @author Michał Żarnecki https://github.com/rzarno
* @param array $verticies An array of verticies names
* @param Edge[] $edges An array of edges
* @return string $start The starting vertex
* @param array $verticesNames An array of vertices names
* @param GraphEdge[] $edges An array of edges
* @param string $start The starting vertex
* @return array An array of shortest paths from $start to all other vertices
*/
function bellmanFord(array $verticesNames, array $edges, string $start, bool $verbose = false)
function bellmanFord(array $verticesNames, array $edges, string $start, bool $verbose = false): array
{
$vertices = array_combine($verticesNames, array_fill(0, count($verticesNames), PHP_INT_MAX));

Expand All @@ -30,7 +24,7 @@ function bellmanFord(array $verticesNames, array $edges, string $start, bool $ve
$change = false;
foreach ($vertices as $vertice => $minWeight) {
if ($verbose) {
echo "checking vertice $vertice\n";
echo "checking vertex $vertice\n";
}
if ($start === $vertice) {
$vertices[$vertice] = 0;
Expand All @@ -39,7 +33,8 @@ function bellmanFord(array $verticesNames, array $edges, string $start, bool $ve
foreach ($edges[$vertice] as $edge) {
if ($vertices[$edge->end] > $vertices[$vertice] + $edge->weight) {
if ($verbose) {
echo "replace $vertice " . $vertices[$edge->end] . " with " . $vertices[$vertice] + $edge->weight . "\n ";
echo "replace $vertice " . $vertices[$edge->end] . " with "
. ($vertices[$vertice] + $edge->weight) . "\n ";
}
$vertices[$edge->end] = $vertices[$vertice] + $edge->weight;
$change = true;
Expand Down
43 changes: 43 additions & 0 deletions Graphs/Dijkstras.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/**
* The Dijkstra's algorithm is an algorithm for finding the shortest paths between nodes in a weighted graph.
* (https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm).
*
* @author Michał Żarnecki https://github.com/rzarno
* @param array $verticesNames An array of vertices names
* @param GraphEdge[] $edges An array of edges
* @param string $start The starting vertex
* @return array An array of shortest paths from $start to all other vertices
*/
function dijkstras(array $verticesNames, array $edges, string $start): array
{
$vertices = array_combine($verticesNames, array_fill(0, count($verticesNames), PHP_INT_MAX));
$visitedNodes = [];

$nextVertex = $start;
$vertices[$start] = 0;
while (count($visitedNodes) < count($verticesNames)) { //continue until all nodes are visited
foreach ($edges as $edge) {
if ($edge->start == $nextVertex) { //consider only nodes connected to current one
$vertices[$edge->end] = min($vertices[$edge->end], $vertices[$nextVertex] + $edge->weight);
}
}

// find vertex with current lowest value to be starting point in next iteration
$minVertexName = null;
$minVertexWeight = PHP_INT_MAX;
foreach ($vertices as $name => $weight) {
if (in_array($name, $visitedNodes) || $name == $nextVertex) {
continue;
}
if ($weight <= $minVertexWeight) {
$minVertexName = $name;
$minVertexWeight = $weight;
}
}
$visitedNodes[] = $nextVertex;
$nextVertex = $minVertexName;
}
return $vertices;
}
8 changes: 8 additions & 0 deletions Graphs/GraphEdge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

class GraphEdge
{
public string $start;
public string $end;
public int $weight;
}
Loading
Loading