https://github.com/tlack/atree Skip to content Toggle navigation Sign in * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code Explore + All features + Documentation + GitHub Skills + Blog * Solutions For + Enterprise + Teams + Startups + Education By Solution + CI/CD & Automation + DevOps + DevSecOps Resources + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} tlack / atree Public * Notifications * Fork 4 * Star 87 Stevan Apter-style trees in C++17 87 stars 4 forks Activity Star Notifications * Code * Issues 1 * Pull requests 0 * Actions * Projects 0 * Security * Insights Additional navigation options * Code * Issues * Pull requests * Actions * Projects * Security * Insights tlack/atree This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. master Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 1 branch 0 tags Code * Local * Codespaces * Clone HTTPS GitHub CLI [https://github.com/t] Use Git or checkout with SVN using the web URL. [gh repo clone tlack/] Work fast with our official CLI. Learn more about the CLI. * Open with GitHub Desktop * Download ZIP Sign In Required Please sign in to use Codespaces. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @tlack tlack readme ... 9b84a83 Feb 18, 2017 readme 9b84a83 Git stats * 18 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time README.md readme February 18, 2017 16:31 tree.cpp update code to use verb exhaust instead of recurse, to match psuedocode February 18, 2017 02:51 tree.sh 0 February 17, 2017 21:37 View code [ ] Apter Trees in C++ Who cares? How it works Operations in psuedocode Again, who cares? (Unfounded editorializing) Origins Other common tree implementations Status of this code Thanks README.md Apter Trees in C++ Apter Trees are a simpler representation of trees using just two vectors: [nodevalues, parentindices]. This repo contains a tree-like data type implemented in C++17, in the style of Stevan Apter in Treetable: a case-study in q. Who cares? A tree is a data structure in which values have parent-child relationships to each other. They come in many forms. In most software, trees are implemented like a typical binary tree, where each node contains its own data and a pointer to each of its children, nominally just left and right, which are also nodes. The cycle continues. Using such a data structure can be challenging due to recursion and slow due to cache behavior in modern systems and frequent malloc()s. The concept of who "owns" a tree node in such a system can become complex in multi-layered software. Apter Trees are much faster, easier to reason about, and easier to implement. How it works An Apter tree is implemented as two same-sized arrays. One is a vector (array) of data (we'll call it d). These correspond to the values, or things that each node contains. The other is a vector of parent indices (p). The index of an item in the d vector is used as its key, which we will call c in the examples below. Often, the key/index c will just be an int. So, if we had a dog family tree in which Coco was the father of Molly and Arca, and Arca had a son named Cricket, you might have a data structure like: tree.d = ["Coco", "Molly", "Arca","Cricket"] tree.p = [0,0,0,2] A node with a key of 0 whose parent is zero is the root node. Apter trees require a root node, or the use of -1 to mean "no parent", which is slightly less elegant so I'll ignore it. Computers are very, very fast at manipulating vectors. They're so much faster than pointer operations that comparisons of big-O notation for an algorithm don't play out in practice. Operations in psuedocode The technique is applicable in all languages. This library is written in C++ but I will use psuedocode to explain how it works. * Empty tree tree() = { {d:[], p:[]} } # some sort of [data,parentidxs] vector * Number of nodes nodecnt(t) = { len(t.p) } * Keys of all nodes join(x,y) = { flatten(x,y) } # append to vec. i.e., x.push_back(y), x[]=y, etc. range(x,y) = { # Q til, APL/C++ iota; return [x, x+1, x+2, ...y-1] i=x; ret=[]; while(i++