"We saw that linked lists use nodes linked in a linear fashion.\n",
"\n",
"Each node had a \"next\" (and possibly a reference to \"prev\").\n",
"\n",
"We can use this same idea with additional links to create **Trees**.\n",
"\n",
"We'll start with a classic **binary search tree**.\n",
"\n",
"Each node has a value, and up to two children, \"left\" and \"right\".\n",
"\n",
"Data is stored in the tree such that when a new node is added, if it is less than the current value of a node, it should be stored to the left, and if it is greater, it should be stored to the right.\n"
"Tree traversal is inherently recursive, so we'll use a recursive function to print the tree in sorted order.\n",
"\n",
"Most tree algorithms will operate on the left & right subtrees the same way, so we can write a recursive function that takes a node and calls itself on the left & right subtrees."
"Usually pronounced \"try\" to differentiate it from trees.\n",
"\n",
"A **trie** is a data structure that stores data associated with string keys similar to a dictionary in many ways. (Python `dict`s are a different data structure: **hash tables**.)\n",
"\n",
"A **trie** is a specialized data structure, particularly useful for partial matching of strings. The way the data is stored enables efficient lookup of all strings that start with a given prefix, as well as \"fuzzy search\" where some characters don't match.\n",
"\n",
"Each node in a **trie** contains:\n",
"\n",
"- an fixed-size array of children\n",
"- a value\n",
"\n",
"Let's imagine a simplified version of a **trie** that can only store string keys with the letters \"a\", \"b\", \"c\", and \"d\".\n",
"\n",
"So keys \"a\", \"ba\", \"dddddd\", and \"abcdabcdaabcad\" would all be valid.\n",
"\n",
"Now, instead of `linked_list.next` or `tree_node.left`, we will have four children, so we'll store them in a tuple:"
"Represents a tree with a single key \"a\". The node \"X\" is the 0th child of the root node. It would have no children set, and a value of `1`.\n",
"\n",
"```\n",
" root\n",
" / \\\\\\\n",
" X\n",
"//\\\\\n",
"```\n",
"Let's look at a trie where someone has also set `trie[\"aba\"] = 100`\n",
"\n",
"\n",
"```\n",
" root\n",
" / \\\\\\\n",
" X \n",
" /|\\\\\n",
" Y\n",
" /\\\\\\\n",
" Z \n",
" //\\\\\n",
"```\n",
"\n",
"Each node has four children, the 0th child being associated with the value \"a\", the 1st with \"b\", and so on.\n",
"\n",
"- X is the same as before `value=1`. It now has a child node \"Y\" in 1st position, associated with \"b\". \n",
"- Y has no `value` set, because it only exists to build out the tree in this case. It has a child at \"a\" position (0).\n",
"- Z is at a terminal position and would have `value=100`. Since the path from the root is \"aba\" that is the key associated with the value."
]
},
{
"cell_type": "markdown",
"id": "3c397fb5-0503-4d8e-a13d-58b6d5cd6943",
"metadata": {},
"source": [
"### Lookup Algorithm\n",
"\n",
"Traversing the tree is done by a simple recursive algorithm:\n",
"\n",
"- if there are more letters in the key: convert the next one to an index and traverse to that child node\n",
"- if there are no more letters: the current node is the destination\n",
"\n",
"The correct behavior when encountering a child node that does not (yet) exist depends on the nature of the traversal:\n",
"\n",
"In a lookup (such as `__getitem__`) the key in question must not be in the **trie**.\n",
"If a value was being set, the node should be created.\n",
"\n",
"### Note/Project Hint\n",
"\n",
"`value=None` will create problems in practice, because you should be able to set `trie[\"abc\"] = None` and not have it treat it as if the data was deleted.\n",
"\n",
"Instead, you will probably want to use different values for unset variables. It is common to make a \"sentinel\" class for this, a class that is used to create a unique value (like `None` being the sole instance of `NoneType`.).\n",
"\n",
"```python\n",
"class DefaultColor:\n",
" \"\"\" Used as a sentinel class. \"\"\"\n",
"\n",
"def set_background(color=DefaultColor):\n",
" \"\"\"\n",
" This function exists to set the background color.\n",
" (In reality, to demonstrate a time when you might treat None and an unset value differently.)\n",
" \n",
" If color is set to None, the background will be transparent.\n",
" If color is not set, the background will default to the user's choice.\n",