Changed documentation backup folder and added generated documentation to docs/
This change is a preparation to migrate the documentation from the gh-pages branch to the docs/ folder in the master branch (once dev is merged)
This commit is contained in:
1 parent
01b8bee8b1
commit
8f64d4bca2
49 files changed
+1507
-1
No files matched your search
@@ -0,0 +1,5 @@
|
||||
<h1 id='bidimap-h'>bidimap.h</h1>
|
||||
<p>A bidirectional map is a map that allows you to create a bijection in both directions between two sets of elements (K <-> V). It is possible to retrieve the value using a key or retrieve a key using a value. The naming is simply used to differentiate between one set of elements and the other set of elements. There is no difference between key and value since both can be keys and/or values.</p>
|
||||
<h2 id='bidimap-implementation'>BidiMap Implementation</h2>
|
||||
<p>This implementation uses two arrays of pointers to an entry containing both the key and the value. Robin Hood hashing is used to minimize worst case scenarios.</p>
|
||||
<h2 id='bidimap-generation-macro'>BidiMap Generation Macro</h2><h2 id='bidimap-structures'>BidiMap Structures</h2><h3 id='members'>Members</h3><h2 id='bidimap-functions'>BidiMap Functions</h2><h2 id='bidimap-callback-table'>BidiMap Callback Table</h2>
|
||||
@@ -0,0 +1,114 @@
|
||||
<h1 id='deque-h'>deque.h</h1>
|
||||
<p>A Deque, also known as a double-ended queue, is a linear data structure that is able to add and remove elements from both ends. It can also be thought of a double-ended stack since you can push and pop elements from two ends. The Deque can also be used as a Queue. The only elements accessible from a Deque ar the two elements at its ends (front element and back element).</p>
|
||||
<h2 id='deque-implementation'>Deque Implementation</h2>
|
||||
<p>This implementation uses a circular buffer (ring buffer or cyclic buffer) in order to operate on O(1) for push and pop on either ends. The only case where it takes longer than O(1) is when the buffer is reallocated. If it was implemented as a regular array, adding or removing elements from the front would take O(N) due to the need to shift all elements in the Deque.</p>
|
||||
|
||||
<p>Two indices are kept track of. The <code>front</code> index and the <code>rear</code> index. These represent the both ends of the Deque. If an index reaches one end of the real buffer, they wrap around to the other end and an element is added there. This abstracts the real buffer as a circular buffer with the cost os constantly checking for boundaries and using the modulo operator.</p>
|
||||
<h2 id='deque-generation-macro'>Deque Generation Macro</h2>
|
||||
<p><code>CMC_GENERATE_DEQUE(PFX, SNAME, V)</code></p>
|
||||
|
||||
<table><thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead><tbody>
|
||||
<tr>
|
||||
<td><code>PFX</code></td>
|
||||
<td>Functions namespace or prefix</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>SNAME</code></td>
|
||||
<td>Structure name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>V</code></td>
|
||||
<td>Element type</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h2 id='deque-structures'>Deque Structures</h2>
|
||||
<table><thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead><tbody>
|
||||
<tr>
|
||||
<td><code>struct SNAME</code></td>
|
||||
<td>A double-ended queue data structure</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>struct SNAME##_iter</code></td>
|
||||
<td>A double-ended queue iterator</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3 id='members'>Members</h3>
|
||||
<table><thead>
|
||||
<tr>
|
||||
<th><code>struct SNAME</code></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead><tbody>
|
||||
<tr>
|
||||
<td><code>V *buffer</code></td>
|
||||
<td>Dynamic circular array of elements.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size_t capacity</code></td>
|
||||
<td>Current circular array capacity.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size_t count</code></td>
|
||||
<td>Current amount of elements.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size_t front</code></td>
|
||||
<td>Index representing the front of the deque.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size_t rear</code></td>
|
||||
<td>Index representing the back of the deque.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>it_start</code> <sup>[1]</sup></td>
|
||||
<td>Function that returns an iterator to the start of the deque.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>it_end</code> <sup>[2]</sup></td>
|
||||
<td>Function that returns an iterator to the end of the deque.</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
|
||||
<ol>
|
||||
<li>Full definition: <code>struct SNAME##_iter (*it_start)(struct SNAME *);</code>.</li>
|
||||
<li>Full definition: <code>struct SNAME##_iter (*it_end)(struct SNAME *);</code>.</li>
|
||||
</ol>
|
||||
|
||||
<table><thead>
|
||||
<tr>
|
||||
<th><code>struct SNAME##_iter</code></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead><tbody>
|
||||
<tr>
|
||||
<td><code>struct SNAME *target</code></td>
|
||||
<td>Deque being iterated over.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size_t cursor</code></td>
|
||||
<td>Cursor's current position (index).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>size_t index</code></td>
|
||||
<td>Relative index to all elements in the iteration.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>bool start</code></td>
|
||||
<td>If the iterator reached the start of the iteration.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>bool end</code></td>
|
||||
<td>If the iterator reached the end of iteration.</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h2 id='deque-functions'>Deque Functions</h2><h2 id='deque-callback-table'>Deque Callback Table</h2>
|
||||
@@ -0,0 +1,6 @@
|
||||
<h1 id='hashmap-h'>hashmap.h</h1>
|
||||
<p>A HashMap is an implementation of a Map with unique keys, where every key is mapped to a value (K -> V). The keys are not sorted. To access a value you must specify a key. This key is hashed to a number that uniquely represents it and through this it is possible to find in which position of an array of buckets the value is.</p>
|
||||
<h2 id='hashmap-implementation'>HashMap Implementation</h2>
|
||||
<p>The HashMap is implemented as a flat HashTable meaning that every entry is allocated when the collection is initialized, but they are all empty.</p>
|
||||
|
||||
<p>The HashTable uses <a href="https://en.wikipedia.org/wiki/Open_addressing">Open Addressing</a> and <a href="https://en.wikipedia.org/wiki/Linear_probing">Linear Probing</a> to resolve collisions along with <a href="https://en.wikipedia.org/wiki/Hash_table">Robin Hood Hashing</a> to minimize the worst case scenarios.</p>
|
||||
@@ -0,0 +1,6 @@
|
||||
<h1 id='hashset-h'>hashset.h</h1>
|
||||
<p>A HashSet is an implementation of a Set with unique keys. The keys are not sorted. It is implemented as a flat hashtable with linear probing and robin hood hashing.</p>
|
||||
<h2 id='hashset-implementation'>HashSet Implementation</h2>
|
||||
<p>The HashSet is implemented as a flat HashTable meaning that every entry is allocated when the collection is initialized, but they are all empty.</p>
|
||||
|
||||
<p>The HashTable uses <a href="https://en.wikipedia.org/wiki/Open_addressing">Open Addressing</a> and <a href="https://en.wikipedia.org/wiki/Linear_probing">Linear Probing</a> to resolve collisions along with <a href="https://en.wikipedia.org/wiki/Hash_table">Robin Hood Hashing</a> to minimize the worst case scenarios.</p>
|
||||
@@ -0,0 +1,24 @@
|
||||
<h1 id='heap-h'>heap.h</h1>
|
||||
<p>The Heap is a specialized tree-based data structure which is essentially a complete tree that satisfies the heap property:</p>
|
||||
|
||||
<p><strong>MaxHeap</strong></p>
|
||||
|
||||
<ul>
|
||||
<li>- The root node is the greatest element of the unique set of keys.</li>
|
||||
<li>- A node key is always greater than or equal to its children keys.</li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Minheap</strong></p>
|
||||
|
||||
<ul>
|
||||
<li>- The root node is the smallest element of the unique set of keys.</li>
|
||||
<li>- A node Key is always greater than or equal to its children keys.</li>
|
||||
</ul>
|
||||
|
||||
<p>The heap is mostly used to implement priority queues. Sometimes it can also be used to sort elements. There are three main functions:</p>
|
||||
|
||||
<ul>
|
||||
<li>insert : Adds an element to the heap</li>
|
||||
<li>remove_(min/max): Removes the min/max element from the heap</li>
|
||||
<li>min/max : Accesses the min/max element from the heap</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,10 @@
|
||||
<h1 id='intervalheap-h'>intervalheap.h</h1>
|
||||
<p>An interval heap is a specialized heap with:</p>
|
||||
|
||||
<ul>
|
||||
<li>O(1) - Find Min</li>
|
||||
<li>O(1) - Find Max</li>
|
||||
<li>O(log n) - Insert</li>
|
||||
<li>O(log n) - Remove Min</li>
|
||||
<li>O(log n) - Remove Max</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,4 @@
|
||||
<h1 id='linkedlist-h'>linkedlist.h</h1>
|
||||
<p>A LinkedList is a linear collection of elements, whose order is not given by their physical placement in memory. Instead, each element points to the next (singly-linked list) and to a previous one (doubly-linked list). It consists of nodes connected by these next or previous pointers. Unlike an array, the LinkedList can indefinitely grow.</p>
|
||||
<h2 id='linkedlist-implementation'>LinkedList Implementation</h2>
|
||||
<p>The LinkedList is implemented as a doubly-linked list and allows insertions and removals at both ends in O(1) and in a given index in O(N). The list has a head and tail pointer. The head points to the first element in the sequence and tail points to the last.</p>
|
||||
@@ -0,0 +1,8 @@
|
||||
<h1 id='list-h'>list.h</h1>
|
||||
<p>A List is a Dynamic Array that store its elements contiguously. It has an internal buffer that is pre-allocated with a greater capacity than necessary in order to foresee new elements being added. The items can be added at both ends of the list and at the middle (with a given index).</p>
|
||||
<h2 id='list-implementation'>List Implementation</h2>
|
||||
<p>Insertions at the start are more costly as it is necessary to shift all elements one position to the right to give space to a new element being added at index 0. Insertions at the end are instantaneous as long as there is enough space in the buffer. Insertions at the middle will be based on an index. The index represents where the element being added will be located once the operation ends. This operation might also need to shift elements. It is also possible to add arrays of elements in the list. When the buffer is filled, it is reallocated with a greater capacity, usually being doubled.</p>
|
||||
|
||||
<p>Removing elements follows the same principle. Removing the front element will require to shift all other elements one position to the left, thus being slower than removing from the end in which is done in constant time. Removing elements in the middle of the list will also require shifting elements to the left. Is is also possible to remove a range of elements or extract them, creating a new list with the removed items.</p>
|
||||
|
||||
<p>The iterator is a simple structure that is capable of going back and forwards. Any modifications to the target list during iteration is considered undefined behavior. Its sole purpose is to facilitate navigation through a list.</p>
|
||||
@@ -0,0 +1,14 @@
|
||||
<h1 id='multimap-h'>multimap.h</h1>
|
||||
<p>The MultiMap is a Map that allows for multiple keys. This is a data structure that has a very narrow usage. A Map (either TreeMap or HashMap) can also work like a MultiMap if a certain key is mapped to another collection.</p>
|
||||
|
||||
<p><code>Map<K = int, V = List<int>></code> maps an integer to a list of integer.</p>
|
||||
|
||||
<p><code>MultiMap<K = int, V = int></code> maps many integer keys to integer values.</p>
|
||||
|
||||
<p>The difference is that in a MultiMap you can store keys that are the same but might be different instances of the same value. This is also relevant if your data type is more complex like a struct where its ID is the same but some other members of this data type are different.</p>
|
||||
<h2 id='multimap-implementation'>MultiMap Implementation</h2>
|
||||
<p>The map uses separate chaining and robin hood hashing. Its internal buffer is made of a pair of pointers to entries that represent a linked list. So accessing map->buffer[0] would give the first pair of pointers. Each entry has both a pointer to a previous entry and a next entry. This design choice was made so that every collection in this library has a two-way iterator with a very few exceptions.</p>
|
||||
|
||||
<p>Each entry is composed of a Key and a Value. Entries with the same key should always hash to the same linked list. Also, keys that hash to the same bucket will also be in the same linked list.</p>
|
||||
|
||||
<p>The order of inserting and removing the same keys will behave like a FIFO. So the first key added will be the first to be removed.</p>
|
||||
@@ -0,0 +1,2 @@
|
||||
<h1 id='multiset-h'>multiset.h</h1>
|
||||
<p>In mathematics, a multiset is a modification of the concept of a set that, unlike a set, allows for multiple instances for each of its elements. The positive integer number of instances, given for each element is called the multiplicity of this element in the multiset. A MultiSet also has a cardinality which equals the sum of the multiplicities of its elements.</p>
|
||||
@@ -0,0 +1,10 @@
|
||||
<h1 id='queue-h'>queue.h</h1>
|
||||
<p>A Queue is a First-In First-out (or Last-in Last-out) data structure. It is a Dynamic Circular Array where elements are added from one end of the array and removed from the other end. The circular array here (also known as circular buffer or ring buffer) is very important so that both adding and removing elements from the Queue are done instantly. The array is linear but with the modulo operator it is treated as a circular sequence of elements.</p>
|
||||
<h2 id='queue-implementation'>Queue Implementation</h2>
|
||||
<p>If the Queue was implemented as a regular Dynamic Array, when adding or removing an element at the front, it would be necessary to shift all elements currently present in the Queue and this would add up a lot of computing time. Shifting <code>100000</code> elements in memory by one position every time an element is added to the Queue is simply not efficient.</p>
|
||||
|
||||
<p>The Queue has two ends. The <code>front</code> and <code>back</code>. In this implementation all elements are added to the back of the Queue and removed from the front, which is more or less how queues work in real life. Unlike a Stack that only has operations at one end of the buffer, the Queue needs to be implemented as a circular array in order to quickly add or remove elements.</p>
|
||||
|
||||
<p>The Queue has three main functions: <code>enqueue</code> which adds an element to the Queue; <code>dequeue</code> which removes an element from the Queue; and <code>peek</code> which return the element at the front of the Queue, that is, the next element to be removed from it.</p>
|
||||
|
||||
<p>The Queue is used in many applications where a resource is shared among multiple consumers and the Queue is responsible for scheduling the access to the resource.</p>
|
||||
@@ -0,0 +1,2 @@
|
||||
<h1 id='sortedlist-h'>sortedlist.h</h1>
|
||||
<p>A SortedList is a dynamic array, meaning that you can store as many elements as you like and when its capacity is full, the buffer is reallocated. The elements are only sorted when a certain action requires that the array is sorted like accessing min() or max(). This prevents the array from being sorted after every insertion or removal. The array is sorted using a variation of quick sort that uses insertion sort for small partitions.</p>
|
||||
@@ -0,0 +1,6 @@
|
||||
<h1 id='stack-h'>stack.h</h1>
|
||||
<p>A Stack is a Last-in First-out (or First-in Last-out) data structure used in a variety of algorithms. It is a Dynamic Array that can only add or remove its elements at the end of the buffer, in this case, it represents the top of the stack.</p>
|
||||
<h2 id='stack-implementation'>Stack Implementation</h2>
|
||||
<p>It has three main functions: <code>push</code> which adds an element at the top of the stack; <code>pop</code> which removes the top element from the stack; and <code>top</code> which returns the top element without removing it (it is also sometimes called <code>peek</code>).</p>
|
||||
|
||||
<p>A Stack is used in algorithms like backtracking, depth-first search, expression evaluation, syntax parsing and many more.</p>
|
||||
@@ -0,0 +1,2 @@
|
||||
<h1 id='treemap-h'>treemap.h</h1>
|
||||
<p>A TreeMap is an implementation of a Map that keeps its keys sorted. Like a Map, it has only unique keys. This implementation uses a balanced binary tree called AVL Tree that uses the height of nodes to keep its keys balanced.</p>
|
||||
@@ -0,0 +1,2 @@
|
||||
<h1 id='treeset-h'>treeset.h</h1>
|
||||
<p>A TreeSet is an implementation of a Set that keeps its elements sorted. Like a Set it has only unique keys. This implementation uses a balanced binary tree called AVL Tree that uses the height of nodes to keep its keys balanced.</p>
|
||||
Reference in new issue
Block a user