diff --git a/AVL Tree/README.markdown b/AVL Tree/README.markdown index 355204587..a9218203a 100644 --- a/AVL Tree/README.markdown +++ b/AVL Tree/README.markdown @@ -1,6 +1,6 @@ # AVL Tree -An AVL tree is a self-balancing form of a [binary search tree](../Binary Search Tree/), in which the height of subtrees differ at most by only 1. +An AVL tree is a self-balancing form of a [binary search tree](../Binary%20Search%20Tree/), in which the height of subtrees differ at most by only 1. A binary tree is *balanced* when its left and right subtrees contain roughly the same number of nodes. That is what makes searching the tree really fast. But if a binary search tree is unbalanced, searching can become really slow. @@ -8,7 +8,7 @@ This is an example of an unbalanced tree: ![Unbalanced tree](Images/Unbalanced.png) -All the children are in the left branch and none are in the right. This is essentially the same as a [linked list](../Linked List/). As a result, searching takes **O(n)** time instead of the much faster **O(log n)** that you'd expect from a binary search tree. +All the children are in the left branch and none are in the right. This is essentially the same as a [linked list](../Linked%20List/). As a result, searching takes **O(n)** time instead of the much faster **O(log n)** that you'd expect from a binary search tree. A balanced version of that tree would look like this: @@ -78,7 +78,7 @@ Insertion never needs more than 2 rotations. Removal might require up to __log(n Most of the code in [AVLTree.swift](AVLTree.swift) is just regular [binary search tree](../Binary Search Tree/) stuff. You'll find this in any implementation of a binary search tree. For example, searching the tree is exactly the same. The only things that an AVL tree does slightly differently are inserting and deleting the nodes. -> **Note:** If you're a bit fuzzy on the regular operations of a binary search tree, I suggest you [catch up on those first](../Binary Search Tree/). It will make the rest of the AVL tree easier to understand. +> **Note:** If you're a bit fuzzy on the regular operations of a binary search tree, I suggest you [catch up on those first](../Binary%20Search%20Tree/). It will make the rest of the AVL tree easier to understand. The interesting bits are in the `balance()` method which is called after inserting or deleting a node. @@ -86,6 +86,6 @@ The interesting bits are in the `balance()` method which is called after inserti [AVL tree on Wikipedia](https://en.wikipedia.org/wiki/AVL_tree) -AVL tree was the first self-balancing binary tree. These days, the [red-black tree](../Red-Black Tree/) seems to be more popular. +AVL tree was the first self-balancing binary tree. These days, the [red-black tree](../Red-Black%20Tree/) seems to be more popular. *Written for Swift Algorithm Club by Mike Taghavi and Matthijs Hollemans* diff --git a/Big-O Notation.markdown b/Big-O Notation.markdown index 8cb988168..09fbb04aa 100644 --- a/Big-O Notation.markdown +++ b/Big-O Notation.markdown @@ -19,6 +19,6 @@ Big-O | Name | Description Often you don't need math to figure out what the Big-O of an algorithm is but you can simply use your intuition. If your code uses a single loop that looks at all **n** elements of your input, the algorithm is **O(n)**. If the code has two nested loops, it is **O(n^2)**. Three nested loops gives **O(n^3)**, and so on. -Note that Big-O notation is an estimate and is only really useful for large values of **n**. For example, the worst-case running time for the [insertion sort](Insertion Sort/) algorithm is **O(n^2)**. In theory that is worse than the running time for [merge sort](Merge Sort/), which is **O(n log n)**. But for small amounts of data, insertion sort is actually faster, especially if the array is partially sorted already! +Note that Big-O notation is an estimate and is only really useful for large values of **n**. For example, the worst-case running time for the [insertion sort](Insertion%20Sort/) algorithm is **O(n^2)**. In theory that is worse than the running time for [merge sort](Merge Sort/), which is **O(n log n)**. But for small amounts of data, insertion sort is actually faster, especially if the array is partially sorted already! If you find this confusing, don't let this Big-O stuff bother you too much. It's mostly useful when comparing two algorithms to figure out which one is better. But in the end you still want to test in practice which one really is the best. And if the amount of data is relatively small, then even a slow algorithm will be fast enough for practical use. diff --git a/Binary Search Tree/README.markdown b/Binary Search Tree/README.markdown index bd2a00c9e..a3a84c03d 100644 --- a/Binary Search Tree/README.markdown +++ b/Binary Search Tree/README.markdown @@ -1,6 +1,6 @@ # Binary Search Tree (BST) -A binary search tree is a special kind of [binary tree](../Binary Tree/) (a tree in which each node has at most two children) that performs insertions and deletions such that the tree is always sorted. +A binary search tree is a special kind of [binary tree](../Binary%20Tree/) (a tree in which each node has at most two children) that performs insertions and deletions such that the tree is always sorted. If you don't know what a tree is or what it is for, then [read this first](../Tree/). @@ -49,7 +49,7 @@ If we were looking for the value `5` in the example, it would go as follows: ![Searching the tree](Images/Searching.png) -Thanks to the structure of the tree, searching is really fast. It runs in **O(h)** time. If you have a well-balanced tree with a million nodes, it only takes about 20 steps to find anything in this tree. (The idea is very similar to [binary search](../Binary Search) in an array.) +Thanks to the structure of the tree, searching is really fast. It runs in **O(h)** time. If you have a well-balanced tree with a million nodes, it only takes about 20 steps to find anything in this tree. (The idea is very similar to [binary search](../Binary%20Search) in an array.) ## Traversing the tree @@ -535,7 +535,7 @@ The code for `successor()` works the exact same way but mirrored: Both these methods run in **O(h)** time. -> **Note:** There is a cool variation called a ["threaded" binary tree](../Threaded Binary Tree) where "unused" left and right pointers are repurposed to make direct links between predecessor and successor nodes. Very clever! +> **Note:** There is a cool variation called a ["threaded" binary tree](../Threaded%20Binary%20Tree) where "unused" left and right pointers are repurposed to make direct links between predecessor and successor nodes. Very clever! ### Is the search tree valid? @@ -713,11 +713,11 @@ The root node is in the middle; a dot means there is no child at that position. A binary search tree is *balanced* when its left and right subtrees contain roughly the same number of nodes. In that case, the height of the tree is *log(n)*, where *n* is the number of nodes. That's the ideal situation. -However, if one branch is significantly longer than the other, searching becomes very slow. We end up checking way more values than we'd ideally have to. In the worst case, the height of the tree can become *n*. Such a tree acts more like a [linked list](../Linked List/) than a binary search tree, with performance degrading to **O(n)**. Not good! +However, if one branch is significantly longer than the other, searching becomes very slow. We end up checking way more values than we'd ideally have to. In the worst case, the height of the tree can become *n*. Such a tree acts more like a [linked list](../Linked%20List/) than a binary search tree, with performance degrading to **O(n)**. Not good! One way to make the binary search tree balanced is to insert the nodes in a totally random order. On average that should balance out the tree quite nicely. But it doesn't guarantee success, nor is it always practical. -The other solution is to use a *self-balancing* binary tree. This type of data structure adjusts the tree to keep it balanced after you insert or delete nodes. See [AVL tree](../AVL Tree) and [red-black tree](../Red-Black Tree) for examples. +The other solution is to use a *self-balancing* binary tree. This type of data structure adjusts the tree to keep it balanced after you insert or delete nodes. See [AVL tree](../AVL%20Tree) and [red-black tree](../Red-Black%20Tree) for examples. ## See also diff --git a/Binary Search/README.markdown b/Binary Search/README.markdown index c65d0b5fd..09b141e04 100644 --- a/Binary Search/README.markdown +++ b/Binary Search/README.markdown @@ -12,7 +12,7 @@ let numbers = [11, 59, 3, 2, 53, 17, 31, 7, 19, 67, 47, 13, 37, 61, 29, 43, 5, 4 numbers.indexOf(43) // returns 15 ``` -The built-in `indexOf()` function performs a [linear search](../Linear Search/). In code that looks something like this: +The built-in `indexOf()` function performs a [linear search](../Linear%20Search/). In code that looks something like this: ```swift func linearSearch(_ a: [T], _ key: T) -> Int? { diff --git a/Binary Tree/README.markdown b/Binary Tree/README.markdown index 896116dda..8ce398804 100644 --- a/Binary Tree/README.markdown +++ b/Binary Tree/README.markdown @@ -8,7 +8,7 @@ The child nodes are usually called the *left* child and the *right* child. If a Often nodes will have a link back to their parent but this is not strictly necessary. -Binary trees are often used as [binary search trees](../Binary Search Tree/). In that case, the nodes must be in a specific order (smaller values on the left, larger values on the right). But this is not a requirement for all binary trees. +Binary trees are often used as [binary search trees](../Binary%20Search%20Tree/). In that case, the nodes must be in a specific order (smaller values on the left, larger values on the right). But this is not a requirement for all binary trees. For example, here is a binary tree that represents a sequence of arithmetical operations, `(5 * (a - 10)) + (-4 * (3 / b))`: diff --git a/Bloom Filter/README.markdown b/Bloom Filter/README.markdown index a85d71be4..3fff0a379 100644 --- a/Bloom Filter/README.markdown +++ b/Bloom Filter/README.markdown @@ -18,7 +18,7 @@ An advantage of the Bloom Filter over a hash table is that the former maintains ## Inserting objects into the set -A Bloom Filter is essentially a fixed-length [bit vector](../Bit Set/), an array of bits. When we insert objects, we set some of these bits to `1`, and when we query for objects we check if certain bits are `0` or `1`. Both operations use hash functions. +A Bloom Filter is essentially a fixed-length [bit vector](../Bit%20Set/), an array of bits. When we insert objects, we set some of these bits to `1`, and when we query for objects we check if certain bits are `0` or `1`. Both operations use hash functions. To insert an element in the filter, the element is hashed with several different hash functions. Each hash function returns a value that we map to an index in the array. We then set the bits at these indices to `1` or true. diff --git a/Bounded Priority Queue/README.markdown b/Bounded Priority Queue/README.markdown index 8d47adefb..4e4c89272 100644 --- a/Bounded Priority Queue/README.markdown +++ b/Bounded Priority Queue/README.markdown @@ -1,6 +1,6 @@ # Bounded Priority queue -A bounded priority queue is similar to a regular [priority queue](../Priority Queue/), except that there is a fixed upper bound on the number of elements that can be stored. When a new element is added to the queue while the queue is at capacity, the element with the highest priority value is ejected from the queue. +A bounded priority queue is similar to a regular [priority queue](../Priority%20Queue/), except that there is a fixed upper bound on the number of elements that can be stored. When a new element is added to the queue while the queue is at capacity, the element with the highest priority value is ejected from the queue. ## Example diff --git a/Boyer-Moore/README.markdown b/Boyer-Moore/README.markdown index e821b812e..5b3841eca 100644 --- a/Boyer-Moore/README.markdown +++ b/Boyer-Moore/README.markdown @@ -24,7 +24,7 @@ animals.indexOf(pattern: "🐮") > **Note:** The index of the cow is 6, not 3 as you might expect, because the string uses more storage per character for emoji. The actual value of the `String.Index` is not so important, just that it points at the right character in the string. -The [brute-force approach](../Brute-Force String Search/) works OK, but it's not very efficient, especially on large chunks of text. As it turns out, you don't need to look at _every_ character from the source string -- you can often skip ahead multiple characters. +The [brute-force approach](../Brute-Force%20String%20Search/) works OK, but it's not very efficient, especially on large chunks of text. As it turns out, you don't need to look at _every_ character from the source string -- you can often skip ahead multiple characters. The skip-ahead algorithm is called [Boyer-Moore](https://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm) and it has been around for a long time. It is considered the benchmark for all string search algorithms. diff --git a/Breadth-First Search/README.markdown b/Breadth-First Search/README.markdown index 084f4611a..2ef92fd73 100644 --- a/Breadth-First Search/README.markdown +++ b/Breadth-First Search/README.markdown @@ -148,7 +148,7 @@ This will output: `["a", "b", "c", "d", "e", "f", "g", "h"]` Breadth-first search can be used to solve many problems. A small selection: -* Computing the [shortest path](../Shortest Path/) between a source node and each of the other nodes (only for unweighted graphs). -* Calculating the [minimum spanning tree](../Minimum Spanning Tree (Unweighted)/) on an unweighted graph. +* Computing the [shortest path](../Shortest%20Path/) between a source node and each of the other nodes (only for unweighted graphs). +* Calculating the [minimum spanning tree](../Minimum%20Spanning%20Tree%20(Unweighted)/) on an unweighted graph. *Written by [Chris Pilcher](https://github.com/chris-pilcher) and Matthijs Hollemans* diff --git a/Count Occurrences/README.markdown b/Count Occurrences/README.markdown index 90a9ec2f3..4c65c4219 100644 --- a/Count Occurrences/README.markdown +++ b/Count Occurrences/README.markdown @@ -2,9 +2,9 @@ Goal: Count how often a certain value appears in an array. -The obvious way to do this is with a [linear search](../Linear Search/) from the beginning of the array until the end, keeping count of how often you come across the value. That is an **O(n)** algorithm. +The obvious way to do this is with a [linear search](../Linear%20Search/) from the beginning of the array until the end, keeping count of how often you come across the value. That is an **O(n)** algorithm. -However, if the array is sorted you can do it much faster, in **O(log n)** time, by using a modification of [binary search](../Binary Search/). +However, if the array is sorted you can do it much faster, in **O(log n)** time, by using a modification of [binary search](../Binary%20Search/). Let's say we have the following array: diff --git a/Hash Set/README.markdown b/Hash Set/README.markdown index 368920a1c..fb829c313 100644 --- a/Hash Set/README.markdown +++ b/Hash Set/README.markdown @@ -196,7 +196,7 @@ difference2.allElements() // [5, 6] If you look at the [documentation](http://swiftdoc.org/v2.1/type/Set/) for Swift's own `Set`, you'll notice it has tons more functionality. An obvious extension would be to make `HashSet` conform to `SequenceType` so that you can iterate it with a `for`...`in` loop. -Another thing you could do is replace the `Dictionary` with an actual [hash table](../Hash Table), but one that just stores the keys and doesn't associate them with anything. So you wouldn't need the `Bool` values anymore. +Another thing you could do is replace the `Dictionary` with an actual [hash table](../Hash%20Table), but one that just stores the keys and doesn't associate them with anything. So you wouldn't need the `Bool` values anymore. If you often need to look up whether an element belongs to a set and perform unions, then the [union-find](../Union-Find/) data structure may be more suitable. It uses a tree structure instead of a dictionary to make the find and union operations very efficient. diff --git a/How to Contribute.markdown b/How to Contribute.markdown index 258357e8b..1235f07ff 100644 --- a/How to Contribute.markdown +++ b/How to Contribute.markdown @@ -6,7 +6,7 @@ Want to help out with the Swift Algorithm Club? Great! Take a look at the [list](README.markdown). Any algorithms or data structures that don't have a link yet are up for grabs. -Algorithms in the [Under construction](Under Construction.markdown) area are being worked on. Suggestions and feedback is welcome! +Algorithms in the [Under construction](Under%20Construction.markdown) area are being worked on. Suggestions and feedback is welcome! New algorithms and data structures are always welcome (even if they aren't on the list). diff --git a/Ordered Array/README.markdown b/Ordered Array/README.markdown index ca088c325..974a42cae 100644 --- a/Ordered Array/README.markdown +++ b/Ordered Array/README.markdown @@ -83,7 +83,7 @@ a // [-2, -1, 1, 3, 4, 5, 7, 9, 10] The array's contents will always be sorted from low to high, now matter what. -Unfortunately, the current `findInsertionPoint()` function is a bit slow. In the worst case, it needs to scan through the entire array. We can speed this up by using a [binary search](../Binary Search) to find the insertion point. +Unfortunately, the current `findInsertionPoint()` function is a bit slow. In the worst case, it needs to scan through the entire array. We can speed this up by using a [binary search](../Binary%20Search) to find the insertion point. Here is the new version: diff --git a/Ordered Set/README.markdown b/Ordered Set/README.markdown index 0525a31ed..1c0d5a8ac 100644 --- a/Ordered Set/README.markdown +++ b/Ordered Set/README.markdown @@ -115,7 +115,7 @@ The next function is `indexOf()`, which takes in an object of type `T` and retur } ``` -> **Note:** If you are not familiar with the concept of binary search, we have an [article that explains all about it](../Binary Search). +> **Note:** If you are not familiar with the concept of binary search, we have an [article that explains all about it](../Binary%20Search). However, there is an important issue to deal with here. Recall that two objects can be unequal yet still have the same "value" for the purposes of comparing them. Since a set can contain multiple items with the same value, it is important to check that the binary search has landed on the correct item. diff --git a/Selection Sort/README.markdown b/Selection Sort/README.markdown index c583b47ea..e95749d14 100644 --- a/Selection Sort/README.markdown +++ b/Selection Sort/README.markdown @@ -6,7 +6,7 @@ You are given an array of numbers and need to put them in the right order. The s [ ...sorted numbers... | ...unsorted numbers... ] -This is similar to [insertion sort](../Insertion Sort/), but the difference is in how new numbers are added to the sorted portion. +This is similar to [insertion sort](../Insertion%20Sort/), but the difference is in how new numbers are added to the sorted portion. It works as follows: @@ -108,9 +108,9 @@ The source file [SelectionSort.swift](SelectionSort.swift) has a version of this ## Performance -Selection sort is easy to understand but it performs quite badly, **O(n^2)**. It's worse than [insertion sort](../Insertion Sort/) but better than [bubble sort](../Bubble Sort/). The killer is finding the lowest element in the rest of the array. This takes up a lot of time, especially since the inner loop will be performed over and over. +Selection sort is easy to understand but it performs quite badly, **O(n^2)**. It's worse than [insertion sort](../Insertion%20Sort/) but better than [bubble sort](../Bubble Sort/). The killer is finding the lowest element in the rest of the array. This takes up a lot of time, especially since the inner loop will be performed over and over. -[Heap sort](../Heap Sort/) uses the same principle as selection sort but has a really fast method for finding the minimum value in the rest of the array. Its performance is **O(n log n)**. +[Heap sort](../Heap%20Sort/) uses the same principle as selection sort but has a really fast method for finding the minimum value in the rest of the array. Its performance is **O(n log n)**. ## See also diff --git a/Shell Sort/README.markdown b/Shell Sort/README.markdown index 9c4bdf076..c21c29685 100644 --- a/Shell Sort/README.markdown +++ b/Shell Sort/README.markdown @@ -39,7 +39,7 @@ As you can see, each sublist contains only every 4th item from the original arra We now call `insertionSort()` once on each sublist. -This particular version of [insertion sort](../Insertion Sort/) sorts from the back to the front. Each item in the sublist is compared against the others. If they're in the wrong order, the value is swapped and travels all the way down until we reach the start of the sublist. +This particular version of [insertion sort](../Insertion%20Sort/) sorts from the back to the front. Each item in the sublist is compared against the others. If they're in the wrong order, the value is swapped and travels all the way down until we reach the start of the sublist. So for sublist 0, we swap `4` with `72`, then swap `4` with `64`. After sorting, this sublist looks like: diff --git a/Shortest Path (Unweighted)/README.markdown b/Shortest Path (Unweighted)/README.markdown index a16519260..4c3c34d9c 100644 --- a/Shortest Path (Unweighted)/README.markdown +++ b/Shortest Path (Unweighted)/README.markdown @@ -12,11 +12,11 @@ If the [graph is unweighed](../Graph/), then finding the shortest path is easy: ## Unweighted graph: breadth-first search -[Breadth-first search](../Breadth-First Search/) is a method for traversing a tree or graph data structure. It starts at a source node and explores the immediate neighbor nodes first, before moving to the next level neighbors. As a convenient side effect, it automatically computes the shortest path between a source node and each of the other nodes in the tree or graph. +[Breadth-first search](../Breadth-First%20Search/) is a method for traversing a tree or graph data structure. It starts at a source node and explores the immediate neighbor nodes first, before moving to the next level neighbors. As a convenient side effect, it automatically computes the shortest path between a source node and each of the other nodes in the tree or graph. The result of the breadth-first search can be represented with a tree: -![The BFS tree](../Breadth-First Search/Images/TraversalTree.png) +![The BFS tree](../Breadth-First%20Search/Images/TraversalTree.png) The root of the tree is the node you started the breadth-first search from. To find the distance from node `A` to any other node, we simply count the number of edges in the tree. And so we find that the shortest path between `A` and `F` is 2. The tree not only tells you how long that path is, but also how to actually get from `A` to `F` (or any of the other nodes). @@ -57,7 +57,7 @@ queue.enqueue(element: G) G.distance = C.distance + 1 // result: 2 ``` -This continues until the queue is empty and we've visited all the nodes. Each time we discover a new node, it gets the `distance` of its parent plus 1. As you can see, this is exactly what the [breadth-first search](../Breadth-First Search/) algorithm does, except that we now also keep track of the distance travelled. +This continues until the queue is empty and we've visited all the nodes. Each time we discover a new node, it gets the `distance` of its parent plus 1. As you can see, this is exactly what the [breadth-first search](../Breadth-First%20Search/) algorithm does, except that we now also keep track of the distance travelled. Here's the code: @@ -97,6 +97,6 @@ This will output: Node(label: d, distance: 2), Node(label: e, distance: 2), Node(label: f, distance: 2), Node(label: g, distance: 2), Node(label: h, distance: 3) -> **Note:** This version of `breadthFirstSearchShortestPath()` does not actually produce the tree, it only computes the distances. See [minimum spanning tree](../Minimum Spanning Tree (Unweighted)/) on how you can convert the graph into a tree by removing edges. +> **Note:** This version of `breadthFirstSearchShortestPath()` does not actually produce the tree, it only computes the distances. See [minimum spanning tree](../Minimum%20Spanning%20Tree%20(Unweighted)/) on how you can convert the graph into a tree by removing edges. *Written by [Chris Pilcher](https://github.com/chris-pilcher) and Matthijs Hollemans* diff --git a/Threaded Binary Tree/README.markdown b/Threaded Binary Tree/README.markdown index fd05113d8..8a1c518f1 100644 --- a/Threaded Binary Tree/README.markdown +++ b/Threaded Binary Tree/README.markdown @@ -1,6 +1,6 @@ # Threaded Binary Tree -A threaded binary tree is a special kind of [binary tree](../Binary Tree/) (a +A threaded binary tree is a special kind of [binary tree](../Binary%20Tree/) (a tree in which each node has at most two children) that maintains a few extra variables to allow cheap and fast **in-order traversal** of the tree. We will explore the general structure of threaded binary trees, as well as @@ -17,7 +17,7 @@ The main motivation behind using a threaded binary tree over a simpler and smaller standard binary tree is to increase the speed of an in-order traversal of the tree. An in-order traversal of a binary tree visits the nodes in the order in which they are stored, which matches the underlying ordering of a -[binary search tree](../Binary Search Tree/). This means most threaded binary +[binary search tree](../Binary%20Search%20Tree/). This means most threaded binary trees are also binary search trees. The idea is to visit all the left children of a node first, then visit the node itself, and then visit the right children last. @@ -47,7 +47,7 @@ tree, to **O(n)** to a very unbalanced tree. A threaded binary tree fixes this problem. -> For more information about in-order traversals [see here](../Binary Tree/). +> For more information about in-order traversals [see here](../Binary%20Tree/). ## Predecessors and successors @@ -222,7 +222,7 @@ walking through some boring code, it is best to explain this with an example (although you can read through [the implementation](ThreadedBinaryTree.swift) if you want to know the finer details). Please note that this requires knowledge of binary search trees, so make sure you have -[read this first](../Binary Search Tree/). +[read this first](../Binary%20Search%20Tree/). > Note: we do allow duplicate nodes in this implementation of a threaded binary > tree. We break ties by defaulting insertion to the right. @@ -339,7 +339,7 @@ such as `searching()` for a node in the tree, finding the `depth()` or `height()` of a node, etc. You can check [the implementation](ThreadedBinaryTree.swift) for the full technical details. Many of these methods are inherent to binary search trees as well, so you can -find [further documentation here](../Binary Search Tree/). +find [further documentation here](../Binary%20Search%20Tree/). ## See also diff --git a/Topological Sort/README.markdown b/Topological Sort/README.markdown index 4429a0754..5659dc3fd 100644 --- a/Topological Sort/README.markdown +++ b/Topological Sort/README.markdown @@ -22,7 +22,7 @@ The following is not a valid topological sort for this graph, since **X** and ** Let's consider that you want to learn all the algorithms and data structures from the Swift Algorithm Club. This might seem daunting at first but we can use topological sort to get things organized. -Since you're learning about topological sort, let's take this topic as an example. What else do you need to learn first before you can fully understand topological sort? Well, topological sort uses [depth-first search](../Depth-First Search/) as well as a [stack](../Stack/). But before you can learn about the depth-first search algorithm, you need to know what a [graph](../Graph/) is, and it helps to know what a [tree](../Tree/) is. In turn, graphs and trees use the idea of linking objects together, so you may need to read up on that first. And so on... +Since you're learning about topological sort, let's take this topic as an example. What else do you need to learn first before you can fully understand topological sort? Well, topological sort uses [depth-first search](../Depth-First%20Search/) as well as a [stack](../Stack/). But before you can learn about the depth-first search algorithm, you need to know what a [graph](../Graph/) is, and it helps to know what a [tree](../Tree/) is. In turn, graphs and trees use the idea of linking objects together, so you may need to read up on that first. And so on... If we were to represent these objectives in the form of a graph it would look as follows: diff --git a/Tree/README.markdown b/Tree/README.markdown index 529a68cf1..440d9c9a4 100644 --- a/Tree/README.markdown +++ b/Tree/README.markdown @@ -16,7 +16,7 @@ The pointers in a tree do not form cycles. This is not a tree: ![Not a tree](Images/Cycles.png) -Such a structure is called a [graph](../Graph/). A tree is really a very simple form of a graph. (In a similar vein, a [linked list](../Linked List/) is a simple version of a tree. Think about it!) +Such a structure is called a [graph](../Graph/). A tree is really a very simple form of a graph. (In a similar vein, a [linked list](../Linked%20List/) is a simple version of a tree. Think about it!) This article talks about a general-purpose tree. That's a tree without any kind of restrictions on how many children each node may have, or on the order of the nodes in the tree. @@ -119,7 +119,7 @@ We often use the following definitions when talking about trees: - **Depth of a node.** The number of links between this node and the root node. For example, the depth of `tea` is 2 because it takes two jumps to reach the root. (The root itself has depth 0.) -There are many different ways to construct trees. For example, sometimes you don't need to have a `parent` property at all. Or maybe you only need to give each node a maximum of two children -- such a tree is called a [binary tree](../Binary Tree/). A very common type of tree is the [binary search tree](../Binary Search Tree/) (or BST), a stricter version of a binary tree where the nodes are ordered in a particular way to speed up searches. +There are many different ways to construct trees. For example, sometimes you don't need to have a `parent` property at all. Or maybe you only need to give each node a maximum of two children -- such a tree is called a [binary tree](../Binary%20Tree/). A very common type of tree is the [binary search tree](../Binary%20Search%20Tree/) (or BST), a stricter version of a binary tree where the nodes are ordered in a particular way to speed up searches. The general purpose tree I've shown here is great for describing hierarchical data, but it really depends on your application what kind of extra functionality it needs to have. diff --git a/Under Construction.markdown b/Under Construction.markdown index 0c59d90c1..be53e01b0 100644 --- a/Under Construction.markdown +++ b/Under Construction.markdown @@ -5,27 +5,27 @@ Here you'll find algorithms that are currently under construction. Suggestions a ### Sorting Special-purpose sorts: - - [Radix Sort](Radix Sort/) + - [Radix Sort](Radix%20Sort/) ### Special-purpose sorts: -- [Bucket Sort](Bucket Sort/) +- [Bucket Sort](Bucket%20Sort/) ### Queues -- [Bounded Priority Queue](Bounded Priority Queue). A queue that is bounded to have a limited number of elements. +- [Bounded Priority Queue](Bounded%20Priority%20Queue). A queue that is bounded to have a limited number of elements. ### Trees -- [AVL Tree](AVL Tree/). A binary search tree that balances itself using rotations. -- [Red-Black Tree](Red-Black Tree/) -- [Threaded Binary Tree](Threaded Binary Tree/) -- [Ternary Search Tree](Ternary Search Tree/) +- [AVL Tree](AVL%20Tree/). A binary search tree that balances itself using rotations. +- [Red-Black Tree](Red-Black%20Tree/) +- [Threaded Binary Tree](Threaded%20Binary%20Tree/) +- [Ternary Search Tree](Ternary%20Search%20Tree/) - [Trie](Trie/) -- [Radix Tree](Radix Tree/) +- [Radix Tree](Radix%20Tree/) ### Miscellaneous -- [Minimum Edit Distance](Minimum Edit Distance/). Measure the similarity of two strings by counting the number of operations required to transform one string into the other. +- [Minimum Edit Distance](Minimum%20Edit%20Distance/). Measure the similarity of two strings by counting the number of operations required to transform one string into the other. - [Treap](Treap/) -- [Set Cover (Unweighted)](Set Cover (Unweighted)/) +- [Set Cover (Unweighted)](Set%20Cover%20(Unweighted)/)