diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..53253a8 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms +github: [mirahman] +custom: ["paypal.me/mirahman1221", mizanurrahman.com] diff --git a/.sonarcloud.properties b/.sonarcloud.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.sonarcloud.properties @@ -0,0 +1 @@ + diff --git a/Algorithms/Graph/Dijkstra.php b/Algorithms/Graph/Dijkstra.php index 77b3dbc..864205e 100644 --- a/Algorithms/Graph/Dijkstra.php +++ b/Algorithms/Graph/Dijkstra.php @@ -1,71 +1,73 @@ - - * - */ - -function dijkstra(array $graph, string $source, string $target): array { - $dist = []; - $pred = []; - $Queue = new SplPriorityQueue(); - - foreach ($graph as $v => $adj) { - $dist[$v] = PHP_INT_MAX; - $pred[$v] = null; - $Queue->insert($v, min($adj)); - } - - $dist[$source] = 0; - - while (!$Queue->isEmpty()) { - $u = $Queue->extract(); - if (!empty($graph[$u])) { - foreach ($graph[$u] as $v => $cost) { - if ($dist[$u] + $cost < $dist[$v]) { - $dist[$v] = $dist[$u] + $cost; - $pred[$v] = $u; - } - } - } - } - - $S = new SplStack(); - $u = $target; - $distance = 0; - - while (isset($pred[$u]) && $pred[$u]) { - $S->push($u); - $distance += $graph[$u][$pred[$u]]; - $u = $pred[$u]; - } - - if ($S->isEmpty()) { - return ["distance" => 0, "path" => $S]; - } else { - $S->push($source); - return ["distance" => $distance, "path" => $S]; - } -} - -$graph = [ - 'A' => ['B' => 3, 'C' => 5, 'D' => 9], - 'B' => ['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7], - 'C' => ['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3], - 'D' => ['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2], - 'E' => ['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5], - 'F' => ['C' => 3, 'D' => 2, 'E' => 5], -]; - -$source = "A"; -$target = "F"; - -$result = dijkstra($graph, $source, $target); -extract($result); - -echo "Distance from $source to $target is $distance \n"; -echo "Path to follow : "; - -while (!$path->isEmpty()) { - echo $path->pop() . "\t"; + + * + */ + +function dijkstra(array $graph, string $source, string $target): array { + $dist = []; + $pred = []; + $Queue = new SplPriorityQueue(); + + foreach ($graph as $v => $adj) { + $dist[$v] = PHP_INT_MAX; + $pred[$v] = null; + foreach ($adj as $w => $cost) { + $Queue->insert($w, $cost); + } + } + + $dist[$source] = 0; + + while (!$Queue->isEmpty()) { + $u = $Queue->extract(); + if (!empty($graph[$u])) { + foreach ($graph[$u] as $v => $cost) { + if ($dist[$u] + $cost < $dist[$v]) { + $dist[$v] = $dist[$u] + $cost; + $pred[$v] = $u; + } + } + } + } + + $S = new SplStack(); + $u = $target; + $distance = 0; + + while (isset($pred[$u]) && $pred[$u]) { + $S->push($u); + $distance += $graph[$u][$pred[$u]]; + $u = $pred[$u]; + } + + if ($S->isEmpty()) { + return ["distance" => 0, "path" => $S]; + } else { + $S->push($source); + return ["distance" => $distance, "path" => $S]; + } +} + +$graph = [ + 'A' => ['B' => 3, 'C' => 5, 'D' => 9], + 'B' => ['A' => 3, 'C' => 3, 'D' => 4, 'E' => 7], + 'C' => ['A' => 5, 'B' => 3, 'D' => 2, 'E' => 6, 'F' => 3], + 'D' => ['A' => 9, 'B' => 4, 'C' => 2, 'E' => 2, 'F' => 2], + 'E' => ['B' => 7, 'C' => 6, 'D' => 2, 'F' => 5], + 'F' => ['C' => 3, 'D' => 2, 'E' => 5], +]; + +$source = "E"; +$target = "F"; + +$result = dijkstra($graph, $source, $target); +extract($result); + +echo "Distance from $source to $target is $distance \n"; +echo "Path to follow : "; + +while (!$path->isEmpty()) { + echo $path->pop() . "\t"; } \ No newline at end of file diff --git a/DS/LinkedList/Classes/LinkedList.php b/DS/LinkedList/Classes/LinkedList.php index 1d6bfa3..40dd272 100644 --- a/DS/LinkedList/Classes/LinkedList.php +++ b/DS/LinkedList/Classes/LinkedList.php @@ -69,7 +69,11 @@ public function insertBefore(string $data = NULL, string $query = NULL) { while ($currentNode !== NULL) { if ($currentNode->data === $query) { $newNode->next = $currentNode; - $previous->next = $newNode; + if ($previous === NULL) { + $this->_firstNode = &$newNode; + } else { + $previous->next = $newNode; + } $this->_totalNode++; break; } diff --git a/DS/Tree/.DS_Store b/DS/Tree/.DS_Store new file mode 100644 index 0000000..1ad25cb Binary files /dev/null and b/DS/Tree/.DS_Store differ diff --git a/DS/Tree/Classes/Trie.php b/DS/Tree/Classes/Trie.php new file mode 100644 index 0000000..2fe2292 --- /dev/null +++ b/DS/Tree/Classes/Trie.php @@ -0,0 +1,49 @@ + + * + */ + +namespace DS\Tree\Classes; + +use DS\Tree\Classes\TrieNode; + +class Trie +{ + public $root; + public function __construct() + { + $this->root = new TrieNode; + } + + public function insert(string $key) + { + $key = strtolower($key); + $length = strlen($key); + $pCrawl = $this->root; + for ($level = 0; $level < $length; $level++) { + $index = ord($key[$level]) - ord('a'); + if (is_null($pCrawl->children[$index])) + $pCrawl->children[$index] = new TrieNode(); + + $pCrawl = $pCrawl->children[$index]; + } + $pCrawl->isEndOfWord = true; + } + + public function search(string $key) + { + $key = strtolower($key); + $length = strlen($key); + $pCrawl = $this->root; + for ($level = 0; $level < $length; $level++) { + $index = ord($key[$level]) - ord('a'); + if (is_null($pCrawl->children[$index])) + return false; + + $pCrawl = $pCrawl->children[$index]; + } + return (!is_null($pCrawl) && $pCrawl->isEndOfWord); + } +} diff --git a/DS/Tree/Classes/TrieNode.php b/DS/Tree/Classes/TrieNode.php new file mode 100644 index 0000000..ee49527 --- /dev/null +++ b/DS/Tree/Classes/TrieNode.php @@ -0,0 +1,21 @@ + + * + */ + +namespace DS\Tree\Classes; + +class TrieNode +{ + public $children; + public $isEndOfWord; + const ALPHABETSIZE = 26; + + public function __construct() + { + $this->isEndOfWord = false; + $this->children = array_fill(0,self::ALPHABETSIZE, null); + } +} \ No newline at end of file diff --git a/DS/Tree/Examples/trie.php b/DS/Tree/Examples/trie.php new file mode 100644 index 0000000..23e9ab0 --- /dev/null +++ b/DS/Tree/Examples/trie.php @@ -0,0 +1,30 @@ + + * + */ + +include __DIR__ . '/../../../Vendor/Autoload.php'; + +use \DS\Tree\Classes\Trie; + +try { + $keys = ["dhaka", "bangladesh", "there", "answer", "any", "by", "bye", "their"]; + + $trie = new Trie(); + // Construct trie + for ($i = 0; $i < count($keys); $i++) + $trie->insert($keys[$i]); + + $searches = ["dhaka", "three", "these", "there", "the", "any", "DHAKA", "anyone", "desh"]; + foreach ($searches as $search) { + if ($trie->search($search)) { + echo "$search - is present in the trie \n"; + } else { + echo "$search - is not present in the trie \n"; + } + } +} catch (Exception $e) { + echo $e->getMessage(); +} diff --git a/README.md b/README.md index 45417a4..057c7ab 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Any feedback, bugs or suggestion will be welcomed. - Binary Tree - Binary Search Tree - Tree Traversal (In-order, pre-order, post-order) + - Trie (Simple insert and search operation) 5. Heaps