{"id":15296322,"url":"https://github.com/seboettg/forest","last_synced_at":"2025-08-17T16:15:37.240Z","repository":{"id":62541705,"uuid":"171162510","full_name":"seboettg/Forest","owner":"seboettg","description":"Tree data structures for PHP – containing general tree, binary tree, and AVL tree","archived":false,"fork":false,"pushed_at":"2020-02-07T18:36:38.000Z","size":129,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-13T19:52:44.301Z","etag":null,"topics":["avl","avl-tree","avltree","basic-data-structures","binary-search-tree","datastructures","datastructures-algorithms","php","php7","search-trees","tree-structure","visitor-pattern"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seboettg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-17T19:26:32.000Z","updated_at":"2025-02-19T17:44:11.000Z","dependencies_parsed_at":"2022-11-02T16:15:30.126Z","dependency_job_id":null,"html_url":"https://github.com/seboettg/Forest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/seboettg/Forest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seboettg%2FForest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seboettg%2FForest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seboettg%2FForest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seboettg%2FForest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seboettg","download_url":"https://codeload.github.com/seboettg/Forest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seboettg%2FForest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270871374,"owners_count":24660192,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avl","avl-tree","avltree","basic-data-structures","binary-search-tree","datastructures","datastructures-algorithms","php","php7","search-trees","tree-structure","visitor-pattern"],"created_at":"2024-09-30T18:10:03.592Z","updated_at":"2025-08-17T16:15:37.206Z","avatar_url":"https://github.com/seboettg.png","language":"PHP","readme":"# Forest\n\n[![PHP](https://img.shields.io/badge/PHP-%3E=7.1-green.svg?style=flat)](http://docs.php.net/manual/en/migration71.new-features.php)\n[![Total Downloads](https://poser.pugx.org/seboettg/forest/downloads)](https://packagist.org/packages/seboettg/forest/stats) \n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/seboettg/forest/blob/master/LICENSE)\n[![Build Status](https://scrutinizer-ci.com/g/seboettg/Forest/badges/build.png?b=master)](https://scrutinizer-ci.com/g/seboettg/Forest/build-status/master)\n[![Code Coverage](https://scrutinizer-ci.com/g/seboettg/Forest/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/seboettg/Forest/?branch=master)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/seboettg/Forest/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/seboettg/Forest/?branch=master)\n[![Code Intelligence Status](https://scrutinizer-ci.com/g/seboettg/Forest/badges/code-intelligence.svg?b=master)](https://scrutinizer-ci.com/code-intelligence)\n\n\"Forest\" is a PHP library that contains classes to create tree data structures such as general trees or Binary Search Trees. Furthermore, typical tree traversing strategies are implemented.\n\n## How to use Forest\n\nYou have to distinguish the purpose for using Forest. There are three different implementations: \n* [General Tree](#general-tree)\n* [Binary Tree](#binary-tree)\n* [AVL Tree](#avl-tree)\n\n### General Tree\nA general tree has the following characterics: Each node can have not more than one parent. Only one node can have no parent, this node is the root of the tree. Each node can have any number of children \n\nAssuming you want to create a tree with the following structure:\n```\n                1\n             /     \\\n           2         3\n                   / | \\\n                 4   5   6\n               /  \\\n             7      8\n```\n\nFirst, you have to create an instance of `GeneralTree`. Pass the type of the items you want to add in this tree:\n\n```php\nuse Seboettg\\Forest\\GeneralTree;\nuse Seboettg\\Forest\\Item\\IntegerItem;\n$tree = new GeneralTree(IntegerItem::class);\n```\n\nYou can also add other Items for trees, but be aware that this item MUST implement the `Seboettg\\Forest\\Item\\ItemInterface`.\nNow you can add the items. The very first element must be added with `root()` \n\n```php\n$tree\n    -\u003eroot(new IntegerItem(1)) // add item objects (of type as defined in the constructor)\n        -\u003echild(2) // or simple integers (instance of IntegerItem will created automatically)  \n        -\u003esubTree(new IntegerItem(3))\n            -\u003esubTree(new IntegerItem(4))\n                -\u003echild(new IntegerItem(7))\n                -\u003echild(new IntegerItem(8))\n            -\u003eendSubTree()\n            -\u003echild(new IntegerItem(5))\n            -\u003echild(new IntegerItem(6))\n        -\u003eendSubTree();\n```\n\nTo get the tree root you can do this: `$root = $builder-\u003egetRoot();`.\n\nMore examples you will find in `/examples/generalTree.php`.\n\n### Binary Tree\n\nEach node of a Binary Tree can have only two children. Inserting of children follows an order. For each inserted node the following condition applies: The associated value or label of the left node must be smaller than the associated value or label of the right node. https://en.wikipedia.org/wiki/Binary_tree\n\nAs mentioned a node of a Binary Tree has always two or less children. Unlike the General Tree, the Binary Tree itself decides where the nodes are added, so that the binary node condition met.\n\n#### Sorting with Binary Trees\n\nAssuming you want add the following values to a Binary Tree: d g b f a c e h. This will result in the following tree structure:\n\n```\n          d\n      /       \\\n    b           g\n  /  \\         / \\\n a    c       f   h \n             /\n            e\n```\n\nIf you want to get the tree contents as list and you choose In-order traversal strategy you will get a sorted list, since in in-order strategy the left subtree is visited first, then the root and later the right subtree.\n\n```php\nuse Seboettg\\Forest\\BinaryTree;\nuse Seboettg\\Forest\\General\\TreeTraversalInterface;\nuse Seboettg\\Forest\\Item\\StringItem;\n\n$bst = new BinaryTree(StringItem::class);\nforeach (['d', 'g', 'b', 'f', 'a', 'c', 'e', 'h'] as $char) {\n    $bst-\u003einsert($char);\n}\n\n$list = $bst-\u003etoArrayList(TreeTraversalInterface::TRAVERSE_IN_ORDER);\n// result is ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']\n```\n\n#### Searching: Using Binary Trees as Search Trees ####\n\nAs you can easily see, there is an inherent sorting by the Binary Tree condition. This predestines the this data structure for searching scenarios. Is the tree balanced the worst-case runtime is only O(log n).\n\n```php\n$result = $bst-\u003esearch(new StringItem(\"e\"));\necho $result-\u003egetItem();\n```\n\nBut a simple Binary Tree can become degenerate. Assuming you add all nodes in a pre-sorted order:\n```php\nforeach (['a', 'b', 'c', 'd', 'e'] as $char) {\n    $bst-\u003einsert($char);\n}\n```\nDue to the binary tree condition, the tree now degenerates. Each node will be appended as a right child node, then the tree is nothing else than a linked list.\n\n```\n    a\n   / \\\n      b\n     / \\\n        c\n       / \\\n          d\n         / \\\n            e\n```\nIf you want to use the binary tree for searching, this may have huge impact of the runtime: In worst case the runtime is O(n). \n\nTo prevent this behavior, you can use the AVL Tree.\n\n### AVL Tree\n\nThe AVL Tree is self-balancing binary search tree. It is actual the same as a Binary Tree, but the AVL condition must apply: the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. \n\nThis condition ensures that an AVL Tree cannot degenerate. Therefore it is particularly suitable for searching. To meet this condition, there is a special rebalancing algorithm for modifying operations invented by Georgy Adelson-Velsky and Evgenii Landis. More information about the rebalancing algorithm you will find on [Wikipedia](https://en.wikipedia.org/wiki/AVL_tree#Rebalancing).\n  \n```php\nuse Seboettg\\Forest\\AVLTree;\nuse Seboettg\\Forest\\Item\\StringItem;\n$avl = new AVLTree(StringItem::class);\nforeach (['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] as $char) {\n    $avl-\u003einsert($char);\n}\n```\nThe result is:\n```\n            d\n          /   \\\n        b       f\n       / \\     / \\\n      a   c   e   g\n                   \\\n                    h\n```\n\n### An Example of Binary Search Trees\n\nA possible example is an [address book as you can find it in the examples folder](examples/bst/AddressBook.md). \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseboettg%2Fforest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseboettg%2Fforest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseboettg%2Fforest/lists"}