├── .gitignore ├── README.md ├── algorithms ├── binary-search │ ├── c │ │ └── binarysearch.c │ └── python │ │ └── binarysearch.py ├── bubble-sort │ ├── c │ │ └── bubblesort.c │ └── python │ │ └── bubblesort.py ├── counting-sort │ ├── c │ │ └── countingsort.c │ └── python │ │ └── countingsort.py ├── graph │ └── dijkstra │ │ └── python │ │ └── dijkstra.py ├── heap-sort │ ├── c │ │ └── heapsort.c │ └── python │ │ └── heapsort.py ├── huffman │ ├── huffman.c │ ├── queue.h │ └── tree.h ├── insertion-sort │ ├── c │ │ └── insertion_sort.c │ └── python │ │ └── insertion_sort.py ├── merge-sort │ ├── c │ │ └── mergesort.c │ └── python │ │ └── mergesort.py ├── quick-sort │ ├── c │ │ └── quicksort.c │ └── python │ │ └── quicksort.py ├── radix-sort │ ├── c │ │ └── radixsort.c │ └── python │ │ └── radixsort.py └── selection-sort │ ├── c │ └── selection_sort.c │ └── python │ └── selection_sort.py └── data-structures ├── arrays ├── c │ ├── dynamic_array.c │ └── dynamic_array.h ├── cc │ ├── dynamic_array.cc │ └── dynamic_array.h ├── java │ └── DynamicArray.java └── python │ └── dynamic_array.py ├── binary_search_tree ├── c │ ├── binary_search_tree.c │ └── binary_search_tree.h ├── cc │ ├── binary_search_tree.cc │ └── binary_search_tree.h └── python │ └── binary_search_tree.py ├── binary_tree ├── c │ ├── binary_tree.c │ └── binary_tree.h ├── cc │ ├── binary_tree.cc │ ├── binary_tree.h │ └── queue_linked_list.h └── python │ └── binary_tree.py ├── graph ├── c │ ├── graph_adjacency_lists.c │ ├── graph_adjacency_lists.h │ ├── linked_list.h │ ├── queue.h │ ├── stack.h │ ├── weighted_graph.c │ └── weighted_graph.h └── maze │ ├── README.md │ ├── demo.png │ ├── maze.txt │ └── maze_solver.c ├── hash_table ├── c │ ├── hash_table_open_addressing.c │ └── hash_table_open_addressing.h ├── cc │ ├── hash_table_open_addressing.cc │ └── hash_table_open_addressing.h └── python │ └── hash_table_open_addressing.py ├── heap ├── c │ ├── heap.c │ └── heap.h └── python │ └── heap.py ├── linked_list ├── c │ ├── linked_list.c │ └── linked_list.h ├── cc │ ├── linked_list.cc │ └── linked_list.h └── python │ └── linked_list.py ├── queue ├── c │ ├── queue_array.c │ ├── queue_array.h │ ├── queue_linked_list.c │ └── queue_linked_list.h ├── cc │ ├── queue_array.cc │ ├── queue_array.h │ ├── queue_linked_list.cc │ └── queue_linked_list.h └── python │ └── queue.py └── stack ├── c ├── reverse_polish_notation.c └── reverse_polish_notation.h ├── cc ├── reverse_polish_notation.cc └── reverse_polish_notation.h └── python └── reverse_polish_notation.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.pyc 3 | a.out 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures and Algorithms 2 | 3 | ### References 4 | 1. https://github.com/jwasham/coding-interview-university 5 | 2. https://eduinf.waw.pl/inf/alg/001_search/index.php (in polish) 6 | -------------------------------------------------------------------------------- /algorithms/binary-search/c/binarysearch.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int binary_search(int *arr, int len, int val) 4 | { 5 | int lo = 0, hi = len - 1; 6 | int mid; 7 | 8 | while (lo <= hi) { 9 | mid = (lo + hi) / 2; 10 | if (arr[mid] < val) { 11 | lo = mid + 1; 12 | } else if (arr[mid] > val) { 13 | hi = mid - 1; 14 | } else { 15 | return 1; 16 | } 17 | } 18 | return 0; 19 | } 20 | 21 | int _binary_search_rec(int *arr, int val, int lo, int hi) 22 | { 23 | if (lo > hi) { 24 | return 0; 25 | } 26 | 27 | int mid = (lo + hi) / 2; 28 | 29 | if (arr[mid] < val) { 30 | return _binary_search_rec(arr, val, mid + 1, hi); 31 | } 32 | 33 | if (arr[mid] > val) { 34 | return _binary_search_rec(arr, val, lo, mid - 1); 35 | } 36 | 37 | return 1; 38 | } 39 | 40 | int binary_search_rec(int *arr, int len, int val) 41 | { 42 | return _binary_search_rec(arr, val, 0, len - 1); 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /algorithms/binary-search/python/binarysearch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def binary_search(arr, val): 4 | left, right = 0, len(arr) - 1 5 | while left <= right: 6 | mid = (left + right) // 2 7 | if val > arr[mid]: 8 | left = mid + 1 9 | elif val < arr[mid]: 10 | right = mid - 1 11 | else: 12 | return True 13 | return False 14 | 15 | def _binary_search_rec(arr, val, lo, hi): 16 | if lo > hi: 17 | return False 18 | mid = (lo + hi) // 2 19 | if arr[mid] > val: 20 | return _binary_search_rec(arr, val, lo, mid - 1) 21 | if arr[mid] < val: 22 | return _binary_search_rec(arr, val, mid + 1, hi) 23 | return True 24 | 25 | def binary_search_rec(arr, val): 26 | return _binary_search_rec(arr, val, 0, len(arr) - 1) 27 | 28 | -------------------------------------------------------------------------------- /algorithms/bubble-sort/c/bubblesort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int *a, int *b) 4 | { 5 | int t = *a; 6 | *a = *b; 7 | *b = t; 8 | } 9 | 10 | void bubble_sort(int *a, int n) 11 | { 12 | for (int i = 0; i < n; i++) { 13 | for (int j = 1; j < n - i; j++) { 14 | if (a[j - 1] > a[j]) { 15 | swap(&a[j - 1], &a[j]); 16 | } 17 | } 18 | } 19 | } 20 | 21 | int main(void) 22 | { 23 | int a[] = {5, -1, 3, 8, -4, 0}; 24 | bubble_sort(arr, 6); 25 | return 0; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /algorithms/bubble-sort/python/bubblesort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def bubble_sort(arr): 4 | n = len(arr) 5 | for i in range(n): 6 | for j in range(1, n - i): 7 | if arr[j - 1] > arr[j]: 8 | arr[j - 1], arr[j] = arr[j], arr[j - 1] 9 | 10 | if __name__ == "__main__": 11 | arr = [6, 3, 5, 10, -1, 7, -4] 12 | bubble_sort(arr) 13 | 14 | -------------------------------------------------------------------------------- /algorithms/counting-sort/c/countingsort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int find_max(int *a, int n) 6 | { 7 | int max = a[0]; 8 | for (int i = 1; i < n; i++) { 9 | if (a[i] > max) { 10 | max = a[i]; 11 | } 12 | } 13 | return max; 14 | } 15 | 16 | void countingsort(int *a, int n) 17 | { 18 | int k = find_max(a, n) + 1; 19 | int *c = (int *)malloc(sizeof(int) * k); 20 | int *t = (int *)malloc(sizeof(int) * n); 21 | 22 | if (c == NULL || t == NULL) { 23 | return; 24 | } 25 | 26 | memset(c, 0, k); 27 | 28 | for (int i = 0; i < n; i++) { 29 | c[a[i]]++; 30 | } 31 | 32 | for (int i = 1; i < k; i++) { 33 | c[i] += c[i - 1]; 34 | } 35 | 36 | for (int i = n - 1; i >= 0; i--) { 37 | t[--c[a[i]]] = a[i]; 38 | } 39 | 40 | for (int i = 0; i < n; i++) { 41 | a[i] = t[i]; 42 | } 43 | 44 | free(c); 45 | free(t); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /algorithms/counting-sort/python/countingsort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def find_max(a, n): 4 | max = a[0] 5 | for i in range(1, n): 6 | if a[i] > max: 7 | max = a[i] 8 | return max 9 | 10 | def countingsort(a): 11 | n = len(a) 12 | k = find_max(a, n) + 1 13 | 14 | c = [0] * k 15 | t = [0] * n 16 | 17 | for i in range(n): 18 | c[a[i]] += 1 19 | 20 | for i in range(1, k): 21 | c[i] += c[i - 1] 22 | 23 | for i in range(n - 1, -1, -1): 24 | c[a[i]] -= 1 25 | t[c[a[i]]] = a[i] 26 | 27 | for i in range(n): 28 | a[i] = t[i] 29 | 30 | return a 31 | 32 | -------------------------------------------------------------------------------- /algorithms/graph/dijkstra/python/dijkstra.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from queue import PriorityQueue 4 | 5 | def dijkstra(G, s): 6 | n = len(G) 7 | 8 | D = [float("+inf")] * n 9 | P = [None] * n 10 | V = [False] * n 11 | Q = PriorityQueue() 12 | 13 | D[s] = 0 14 | Q.put((0, s)) 15 | 16 | while Q.qsize() > 0: 17 | _, u = Q.get() 18 | # Skip vertices that have been put to Q with greater weight and have already been processed. 19 | if V[u]: 20 | continue 21 | V[u] = True 22 | 23 | for v, w in G[u]: 24 | if D[v] > D[u] + w: 25 | D[v] = D[u] + w 26 | P[v] = u 27 | Q.put((D[v], v)) 28 | 29 | G = [ 30 | [(1, 7), (5, 1)], 31 | [(0, 7), (2, 10), (5, 3)], 32 | [(1, 10), (3, 4)], 33 | [(2, 4), (4, 3), (5, 7)], 34 | [(3, 3), (5, 2)], 35 | [(0, 1), (1, 3), (3, 7), (4, 2)] 36 | ] 37 | dijkstra(G, 0) 38 | 39 | -------------------------------------------------------------------------------- /algorithms/heap-sort/c/heapsort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LEFT_CHILD(n) (n * 2 + 1) 4 | #define RIGHT_CHILD(n) (n * 2 + 2) 5 | #define PARENT(n) ((n - 1) / 2) 6 | 7 | void swap(int *a, int *b) 8 | { 9 | int t = *a; 10 | *a = *b; 11 | *b = t; 12 | } 13 | 14 | void heapify(int *t, int n, int i) 15 | { 16 | int l = LEFT_CHILD(i); 17 | int r = RIGHT_CHILD(i); 18 | int m = i; 19 | 20 | if (l < n && t[l] > t[m]) m = l; 21 | if (r < n && t[r] > t[m]) m = r; 22 | 23 | if (m != i) { 24 | swap(&t[i], &t[m]); 25 | heapify(t, n, m); 26 | } 27 | } 28 | 29 | void build_heap(int *t, int n) 30 | { 31 | for (int i = PARENT(n - 1); i >= 0; i--) { 32 | heapify(t, n, i); 33 | } 34 | } 35 | 36 | void heap_sort(int *t, int n) 37 | { 38 | build_heap(t, n); 39 | 40 | for (int i = n - 1; i >= 1; i--) { 41 | swap(&t[0], &t[i]); 42 | heapify(t, i, 0); 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /algorithms/heap-sort/python/heapsort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def left(i): 4 | return 2 * i + 1 5 | 6 | def right(i): 7 | return 2 * i + 2 8 | 9 | def parent(i): 10 | return (i - 1) // 2 11 | 12 | def heapify(t, n, i): 13 | l = left(i) 14 | r = right(i) 15 | 16 | m = i 17 | if l < n and t[l] > t[m]: 18 | m = l 19 | if r < n and t[r] > t[m]: 20 | m = r 21 | 22 | if i != m: 23 | t[i], t[m] = t[m], t[i] 24 | heapify(t, n, m) 25 | 26 | def build_heap(t, n): 27 | for i in range(parent(n - 1), -1, -1): 28 | heapify(t, n, i) 29 | 30 | def heapsort(t): 31 | n = len(t) 32 | build_heap(t, n) 33 | 34 | for i in range(n - 1, 0, -1): 35 | t[0], t[i] = t[i], t[0] 36 | heapify(t, i, 0) 37 | 38 | -------------------------------------------------------------------------------- /algorithms/huffman/huffman.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "tree.h" 3 | #include "queue.h" 4 | 5 | #define MAX_CODE_LENGTH 256 6 | 7 | void print_code(int *c, int n) 8 | { 9 | for (int i = 0; i < n; i++) { 10 | printf("%i", c[i]); 11 | } 12 | printf("\n"); 13 | } 14 | 15 | void print_huffman(tree_t *t, int *c, int i) 16 | { 17 | if (t == NULL) { 18 | return; 19 | } 20 | 21 | if (t->ch == 0) { 22 | c[i] = 0; 23 | print_huffman(t->left, c, i + 1); 24 | c[i] = 1; 25 | print_huffman(t->right, c, i + 1); 26 | } else { 27 | printf("%c: ", t->ch); 28 | print_code(c, i); 29 | } 30 | } 31 | 32 | void huffman(const char *s) 33 | { 34 | int freq[256] = {}; 35 | tree_t *t, *a, *b; 36 | 37 | for (int i = 0; s[i] != '\0'; i++) { 38 | freq[s[i]]++; 39 | } 40 | 41 | queue_t *q = queue_init(256); 42 | 43 | for (int i = 0; i < 256; i++) { 44 | if (freq[i] > 0) { 45 | t = tree_init(i, freq[i], NULL, NULL); 46 | queue_enqueue(q, t, t->freq); 47 | } 48 | } 49 | 50 | while (queue_length(q) > 1) { 51 | a = queue_dequeue(q); 52 | b = queue_dequeue(q); 53 | 54 | t = tree_init(0, a->freq + b->freq, a, b); 55 | queue_enqueue(q, t, t->freq); 56 | } 57 | 58 | t = queue_dequeue(q); 59 | int c[MAX_CODE_LENGTH] = {}; 60 | print_huffman(t, c, 0); 61 | } 62 | 63 | int main(void) 64 | { 65 | huffman("qwerty"); 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /algorithms/huffman/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _QUEUE_H_INCLUDED_ 2 | #define _QUEUE_H_INCLUDED_ 3 | 4 | #include 5 | #include 6 | #include "tree.h" 7 | 8 | #define QUEUE_PARENT(n) ((n - 1) / 2) 9 | #define QUEUE_LEFT(n) (n * 2 + 1) 10 | #define QUEUE_RIGHT(n) (n * 2 + 2) 11 | 12 | typedef struct queue_item_s { 13 | tree_t *value; 14 | int prio; 15 | } queue_item_t; 16 | 17 | typedef struct queue_s { 18 | queue_item_t **items; 19 | int len; 20 | int cap; 21 | } queue_t; 22 | 23 | queue_t *queue_init(int cap) 24 | { 25 | queue_t *q = (queue_t *)malloc(sizeof(queue_t)); 26 | q->items = (queue_item_t **)malloc(sizeof(queue_item_t *)); 27 | 28 | for (int i = 0; i < cap; i++) { 29 | q->items[i] = (queue_item_t *)malloc(sizeof(queue_item_t)); 30 | } 31 | 32 | q->len = 0; 33 | q->cap = cap; 34 | return q; 35 | } 36 | 37 | queue_item_t *queue_item_init(tree_t *t, int p) 38 | { 39 | queue_item_t *i = (queue_item_t *)malloc(sizeof(queue_item_t)); 40 | i->value = t; 41 | i->prio = p; 42 | return i; 43 | } 44 | 45 | tree_t *queue_item_remove(queue_item_t *i) 46 | { 47 | tree_t *t = i->value; 48 | free(i); 49 | return t; 50 | } 51 | 52 | void queue_remove(queue_t *q) 53 | { 54 | for (int i = 0; i < q->len; i++) { 55 | queue_item_remove(q->items[i]); 56 | } 57 | free(q); 58 | } 59 | 60 | void queue_swap(queue_item_t **a, queue_item_t **b) 61 | { 62 | queue_item_t *t = *a; 63 | *a = *b; 64 | *b = t; 65 | } 66 | 67 | void queue_siftup(queue_t *q, int i) 68 | { 69 | while (i > 0 && q->items[QUEUE_PARENT(i)]->prio > q->items[i]->prio) { 70 | queue_swap(&q->items[QUEUE_PARENT(i)], &q->items[i]); 71 | i = QUEUE_PARENT(i); 72 | } 73 | } 74 | 75 | void queue_heapify(queue_t *q, int i) 76 | { 77 | int l = QUEUE_LEFT(i); 78 | int r = QUEUE_RIGHT(i); 79 | int m = i; 80 | 81 | if (l < q->len && q->items[l]->prio < q->items[m]->prio) { 82 | m = l; 83 | } 84 | 85 | if (r < q->len && q->items[r]->prio < q->items[m]->prio) { 86 | m = r; 87 | } 88 | 89 | if (m != i) { 90 | queue_swap(&q->items[m], &q->items[i]); 91 | queue_heapify(q, m); 92 | } 93 | } 94 | 95 | void queue_enqueue(queue_t *q, tree_t *t, int p) 96 | { 97 | if (q->len == q->cap) { 98 | return; 99 | } 100 | q->items[q->len++] = queue_item_init(t, p); 101 | queue_siftup(q, q->len - 1); 102 | } 103 | 104 | tree_t *queue_dequeue(queue_t *q) 105 | { 106 | queue_swap(&q->items[0], &q->items[--q->len]); 107 | tree_t *t = queue_item_remove(q->items[q->len]); 108 | queue_heapify(q, 0); 109 | return t; 110 | } 111 | 112 | int queue_length(queue_t *q) 113 | { 114 | return q->len; 115 | } 116 | 117 | #endif // _QUEUE_H_INCLUDED_ 118 | 119 | -------------------------------------------------------------------------------- /algorithms/huffman/tree.h: -------------------------------------------------------------------------------- 1 | #ifndef _TREE_H_INCLUDED_ 2 | #define _TREE_H_INCLUDED_ 3 | 4 | #include 5 | 6 | typedef struct tree_s tree_t; 7 | 8 | typedef struct tree_s { 9 | char ch; 10 | int freq; 11 | tree_t *left; 12 | tree_t *right; 13 | } tree_t; 14 | 15 | tree_t *tree_init(char ch, int freq, tree_t *left, tree_t *right) 16 | { 17 | tree_t *t = (tree_t *)malloc(sizeof(tree_t)); 18 | t->ch = ch; 19 | t->freq = freq; 20 | t->left = left; 21 | t->right = right; 22 | return t; 23 | } 24 | 25 | void tree_remove(tree_t *t) 26 | { 27 | free(t); 28 | } 29 | 30 | #endif // _TREE_H_INCLUDED_ 31 | 32 | -------------------------------------------------------------------------------- /algorithms/insertion-sort/c/insertion_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void insertion_sort(int *arr, int sz) 4 | { 5 | int i, j, key; 6 | 7 | for (i = 1; i < sz; i++) { 8 | key = arr[i]; 9 | j = i - 1; 10 | 11 | while (j >= 0 && arr[j] > key) { 12 | arr[j + 1] = arr[j]; 13 | j--; 14 | } 15 | 16 | arr[j + 1] = key; 17 | } 18 | } 19 | 20 | int main(void) 21 | { 22 | int arr[] = {5, 2, 4, 6, 1, 3}; 23 | insertion_sort(arr, 6); 24 | return 0; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /algorithms/insertion-sort/python/insertion_sort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def insertion_sort(arr, sz): 4 | for i in range(1, sz): 5 | key = arr[i] 6 | j = i - 1 7 | 8 | while j >= 0 and arr[j] > key: 9 | arr[j + 1] = arr[j] 10 | j -= 1 11 | 12 | arr[j + 1] = key 13 | 14 | if __name__ == "__main__": 15 | arr = [5, 2, 4, 6, 1, 3] 16 | insertion_sort(arr, len(arr)) 17 | print(arr) 18 | 19 | -------------------------------------------------------------------------------- /algorithms/merge-sort/c/mergesort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define min(a, b) ((a) < (b) ? (a) : (b)) 4 | 5 | void _merge(int *a, int *c, int lo, int mid, int hi) 6 | { 7 | for (int k = lo; k <= hi; k++) { 8 | c[k] = a[k]; 9 | } 10 | 11 | int i = lo, j = mid + 1; 12 | for (int k = lo; k <= hi; k++) { 13 | if (i > mid) a[k] = c[j++]; 14 | else if (j > hi) a[k] = c[i++]; 15 | else if (c[i] < c[j]) a[k] = c[i++]; 16 | else if (c[i] >= c[j]) a[k] = c[j++]; 17 | } 18 | } 19 | 20 | void _mergesort(int *a, int *c, int lo, int hi) 21 | { 22 | if (hi <= lo) { 23 | return; 24 | } 25 | int mid = lo + (hi - lo) / 2; 26 | _mergesort(a, c, lo, mid); 27 | _mergesort(a, c, mid + 1, hi); 28 | _merge(a, c, lo, mid, hi); 29 | } 30 | 31 | 32 | void mergesort(int *a, int n) 33 | { 34 | int c[n]; 35 | _mergesort(a, c, 0, n - 1); 36 | } 37 | 38 | void mergesort_iter(int *a, int n) 39 | { 40 | int c[n]; 41 | for (int sz = 1; sz < n; sz = sz + sz) { 42 | for (int lo = 0; lo < n - sz; lo += sz + sz) { 43 | _merge(a, c, lo, lo + sz - 1, min(lo + sz + sz - 1, n - 1)); 44 | } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /algorithms/merge-sort/python/mergesort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def _merge(a, c, lo, mid, hi): 4 | for i in range(lo, hi + 1): 5 | c[i] = a[i] 6 | 7 | i, j = lo, mid + 1 8 | for k in range(lo, hi + 1): 9 | if i > mid: 10 | a[k] = c[j]; j += 1 11 | elif j > hi: 12 | a[k] = c[i]; i += 1 13 | elif c[i] < c[j]: 14 | a[k] = c[i]; i += 1 15 | elif c[i] >= c[j]: 16 | a[k] = c[j]; j += 1 17 | return a 18 | 19 | def _mergesort(a, c, lo, hi): 20 | if hi <= lo: 21 | return 22 | mid = lo + (hi - lo) // 2 23 | _mergesort(a, c, lo, mid) 24 | _mergesort(a, c, mid + 1, hi) 25 | return _merge(a, c, lo, mid, hi) 26 | 27 | def mergesort(a): 28 | c = a[:] 29 | return _mergesort(a, c, 0, len(a) - 1) 30 | 31 | -------------------------------------------------------------------------------- /algorithms/quick-sort/c/quicksort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int *a, int *b) 4 | { 5 | int t = *a; 6 | *a = *b; 7 | *b = t; 8 | } 9 | 10 | int partition(int *a, int l, int h) 11 | { 12 | int p = a[h]; 13 | int i = l - 1; 14 | 15 | for (int j = l; j < h; j++) { 16 | if (a[j] < p) { 17 | i += 1; 18 | swap(&a[i], &a[j]); 19 | } 20 | } 21 | 22 | swap(&a[i + 1], &a[h]); 23 | return i + 1; 24 | } 25 | 26 | void _quicksort(int *a, int l, int h) 27 | { 28 | if (l < h) { 29 | int p = partition(a, l, h); 30 | _quicksort(a, l, p - 1); 31 | _quicksort(a, p + 1, h); 32 | } 33 | } 34 | 35 | void quicksort(int *a, int n) 36 | { 37 | return _quicksort(a, 0, n - 1); 38 | } 39 | 40 | int main(void) 41 | { 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /algorithms/quick-sort/python/quicksort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def _partition(a, lo, hi): 4 | p = a[hi] 5 | i = lo - 1 6 | 7 | for j in range(lo, hi): 8 | if a[j] < p: 9 | i += 1 10 | a[i], a[j] = a[j], a[i] 11 | 12 | a[i + 1], a[hi] = a[hi], a[i + 1] 13 | return i + 1 14 | 15 | def _quicksort(a, lo, hi): 16 | if lo < hi: 17 | j = _partition(a, lo, hi) 18 | _quicksort(a, lo, j - 1) 19 | _quicksort(a, j + 1, hi) 20 | 21 | def quicksort(a): 22 | return _quicksort(a, 0, len(a) - 1) 23 | 24 | -------------------------------------------------------------------------------- /algorithms/radix-sort/c/radixsort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int find_max(int *a, int n) 5 | { 6 | int max = a[0]; 7 | for (int i = 1; i < n; i++) { 8 | if (a[i] > max) { max = a[i]; } 9 | } 10 | return max; 11 | } 12 | 13 | void countingsort(int *a, int n, int e) 14 | { 15 | int c[10] = {0}; 16 | 17 | int *t = (int *)malloc(sizeof(int) * n); 18 | if (t == NULL) { 19 | return; 20 | } 21 | 22 | for (int i = 0; i < n; i++) { 23 | c[(a[i] / e) % 10]++; 24 | } 25 | 26 | for (int i = 1; i < 10; i++) { 27 | c[i] += c[i - 1]; 28 | } 29 | 30 | for (int i = n - 1; i >= 0; i--) { 31 | t[--c[(a[i] / e) % 10]] = a[i]; 32 | } 33 | 34 | for (int i = 0; i < n; i++) { 35 | a[i] = t[i]; 36 | } 37 | 38 | free(t); 39 | } 40 | 41 | void radixsort(int *a, int n) 42 | { 43 | int m = find_max(a, n); 44 | for (int e = 1; m / e > 0; e *= 10) { 45 | countingsort(a, n, e); 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /algorithms/radix-sort/python/radixsort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | def countingsort(a, n, e): 4 | c = [0] * 10 5 | t = [0] * n 6 | 7 | for i in range(n): 8 | c[(a[i] // e) % 10] += 1 9 | 10 | for i in range(1, 10): 11 | c[i] += c[i - 1] 12 | 13 | for i in range(n - 1, -1, -1): 14 | c[(a[i] // e) % 10] -= 1 15 | t[c[(a[i] // e) % 10]] = a[i] 16 | 17 | for i in range(n): 18 | a[i] = t[i] 19 | 20 | return a 21 | 22 | def radixsort(a): 23 | n = len(a) 24 | m = max(a) 25 | e = 1 26 | while m // e > 0: 27 | countingsort(a, n, e) 28 | e *= 10 29 | return a 30 | 31 | -------------------------------------------------------------------------------- /algorithms/selection-sort/c/selection_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void selection_sort(int *arr, size_t size) 4 | { 5 | size_t i, j, k; 6 | int t; 7 | 8 | for (i = 0; i < size; i++) { 9 | k = i; 10 | 11 | for (j = i + 1; j < size; j++) { 12 | if (arr[j] > arr[k]) { 13 | k = j; 14 | } 15 | } 16 | 17 | t = arr[i]; 18 | arr[i] = arr[k]; 19 | arr[k] = t; 20 | } 21 | } 22 | 23 | 24 | int main(void) 25 | { 26 | int arr[] = {5, 1, 3, -10, 2, 4}; 27 | size_t n = 6; 28 | 29 | selection_sort(arr, n); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /algorithms/selection-sort/python/selection_sort.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from typing import List 4 | 5 | def selection_sort(arr: List, size: int) -> None: 6 | for i in range(size): 7 | j, k = i + 1, i 8 | 9 | while j < size: 10 | if arr[j] > arr[k]: 11 | k = j 12 | j += 1 13 | 14 | arr[i], arr[k] = arr[k], arr[i] 15 | return None 16 | 17 | if __name__ == "__main__": 18 | arr = [-13, 1, 6, -3, 0, 5, -2, 10] 19 | selection_sort(arr, len(arr)) 20 | -------------------------------------------------------------------------------- /data-structures/arrays/c/dynamic_array.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "dynamic_array.h" 6 | 7 | dynamic_array_t *create_dynamic_array(void) 8 | { 9 | dynamic_array_t *da = (dynamic_array_t *)malloc(sizeof(dynamic_array_t)); 10 | if (da == NULL) { 11 | fprintf(stderr, "Unable to allocate the memory for the dynamic array.\n"); 12 | return NULL; 13 | } 14 | 15 | da->size = 0; 16 | da->capacity = 4; 17 | da->array = (int *)malloc(sizeof(int) * da->capacity); 18 | if (da->array == NULL) { 19 | fprintf(stderr, "Unable to allocate the memory for the array.\n"); 20 | return NULL; 21 | } 22 | return da; 23 | } 24 | 25 | static void resize(dynamic_array_t *da) 26 | { 27 | int *array = (int *)malloc(sizeof(int) * da->capacity * 2); 28 | if (array == NULL) { 29 | fprintf(stderr, "Unable to allocate the memory for the array.\n"); 30 | return; 31 | } 32 | memcpy(array, da->array, sizeof(int) * da->size); 33 | free(da->array); 34 | 35 | da->capacity = da->capacity * 2; 36 | da->array = array; 37 | } 38 | 39 | void push_back(dynamic_array_t *da, int value) 40 | { 41 | if (da->size >= da->capacity) 42 | resize(da); 43 | da->array[da->size++] = value; 44 | } 45 | 46 | int pop_back(dynamic_array_t *da) 47 | { 48 | if (da->size <= 0) 49 | return -1; 50 | return da->array[--da->size]; 51 | } 52 | 53 | int get(dynamic_array_t *da, int index) 54 | { 55 | if (index < 0 || index >= da->size) 56 | return -1; // ERROR: index out of range 57 | return da->array[index]; 58 | } 59 | 60 | void set(dynamic_array_t *da, int index, int value) 61 | { 62 | if (index < 0 || index >= da->size) 63 | return; // ERROR: index out of range 64 | da->array[index] = value; 65 | } 66 | 67 | void insert(dynamic_array_t *da, int index, int value) 68 | { 69 | if (index < 0 || index >= da->size) 70 | return; // ERROR: index out of range 71 | 72 | if (da->size >= da->capacity) 73 | resize(da); 74 | 75 | for (int i = da->size - 1; i >= index; i--) { 76 | da->array[i + 1] = da->array[i]; 77 | } 78 | da->array[index] = value; 79 | da->size++; 80 | } 81 | 82 | void delete(dynamic_array_t *da, int index) 83 | { 84 | if (index < 0 || index >= da->size) 85 | return; // ERROR: index out of range 86 | for (int i = index; i < da->size; i++) { 87 | da->array[i] = da->array[i + 1]; 88 | } 89 | da->size--; 90 | } 91 | 92 | int find(dynamic_array_t *da, int value) 93 | { 94 | for (int i = 0; i < da->size; i++) { 95 | if (da->array[i] == value) 96 | return i; 97 | } 98 | return -1; 99 | } 100 | -------------------------------------------------------------------------------- /data-structures/arrays/c/dynamic_array.h: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_ARRAY_H 2 | #define DYNAMIC_ARRAY_H 3 | 4 | typedef struct dynamic_array 5 | { 6 | int size; 7 | int capacity; 8 | int *array; 9 | } dynamic_array_t; 10 | 11 | dynamic_array_t *create_dynamic_array(void); 12 | 13 | static void resize(dynamic_array_t *da); 14 | 15 | void push_back(dynamic_array_t *da, int value); 16 | 17 | int pop_back(dynamic_array_t *da); 18 | 19 | void insert(dynamic_array_t *da, int index, int value); 20 | 21 | void set(dynamic_array_t *da, int index, int value); 22 | 23 | int get(dynamic_array_t *da, int index); 24 | 25 | void delete(dynamic_array_t *da, int index); 26 | 27 | int find(dynamic_array_t *da, int value); 28 | 29 | #endif // DYNAMIC_ARRAY_H 30 | -------------------------------------------------------------------------------- /data-structures/arrays/cc/dynamic_array.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dynamic_array.h" 3 | 4 | namespace mf 5 | { 6 | 7 | DynamicArray::DynamicArray() : size(0), capacity(4) 8 | { 9 | this->array = std::unique_ptr(new int[this->capacity]); 10 | } 11 | 12 | DynamicArray::~DynamicArray() {} 13 | 14 | int DynamicArray::get_size() const { return this->size; } 15 | 16 | bool DynamicArray::is_empty() const { return this->size == 0; } 17 | 18 | int DynamicArray::get_capacity() const { return this->capacity; } 19 | 20 | void DynamicArray::push_back(int value) 21 | { 22 | if (this->size >= this->capacity) { 23 | this->resize(); 24 | } 25 | this->array[this->size++] = value; 26 | } 27 | 28 | std::optional DynamicArray::pop_back() 29 | { 30 | if (this->size == 0) { 31 | return std::nullopt; 32 | } 33 | return this->array[--this->size]; 34 | } 35 | 36 | void DynamicArray::update(int index, int value) 37 | { 38 | if (index < 0 || index >= this->size) { 39 | return; 40 | } 41 | this->array[index] = value; 42 | } 43 | 44 | std::optional DynamicArray::get(int index) const 45 | { 46 | if (index < 0 || index >= this->size) { 47 | return std::nullopt; // ERROR: index out of range 48 | } 49 | return this->array[index]; 50 | } 51 | 52 | void DynamicArray::insert(int index, int value) 53 | { 54 | if (index < 0 || index >= this->size) { 55 | return; // ERROR: index out of range 56 | } 57 | 58 | if (this->size >= this->capacity) { 59 | this->resize(); 60 | } 61 | 62 | for (int i = this->size - 1; i >= index; i--) { 63 | this->array[i + 1] = this->array[i]; 64 | } 65 | this->array[index] = value; 66 | this->size++; 67 | } 68 | 69 | void DynamicArray::remove(int index) 70 | { 71 | if (index < 0 || index >= this->size) { 72 | return; // ERROR: index out of range 73 | } 74 | 75 | for (int i = index; i < this->size; i++) { 76 | this->array[i] = this->array[i + 1]; 77 | } 78 | this->size--; 79 | } 80 | 81 | std::optional DynamicArray::find(int value) const 82 | { 83 | for (int i = 0; i < this->size; i++) { 84 | if (this->array[i] == value) 85 | return i; 86 | } 87 | return std::nullopt; 88 | } 89 | 90 | void DynamicArray::resize() 91 | { 92 | std::unique_ptr new_array(new int [this->capacity * 2]); 93 | 94 | for (int i = 0; i < this->size; i++) { 95 | new_array[i] = this->array[i]; 96 | } 97 | 98 | this->array = std::move(new_array); 99 | this->capacity = this->capacity * 2; 100 | } 101 | 102 | } // namespace mf 103 | -------------------------------------------------------------------------------- /data-structures/arrays/cc/dynamic_array.h: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_ARRAY_H 2 | #define DYNAMIC_ARRAY_H 3 | 4 | #include 5 | #include 6 | 7 | namespace mf 8 | { 9 | 10 | class DynamicArray 11 | { 12 | private: 13 | int size; 14 | int capacity; 15 | std::unique_ptr array; 16 | 17 | // Resize the capacity of the array (2x). 18 | void resize(); 19 | 20 | public: 21 | // Constructor & destructor 22 | DynamicArray(); 23 | ~DynamicArray(); 24 | 25 | // Return the size of the array. 26 | int get_size() const; 27 | 28 | // Check if the array is empty. 29 | bool is_empty() const; 30 | 31 | // Return the capacity of the array. 32 | int get_capacity() const; 33 | 34 | // Add an item to the end of the array. 35 | void push_back(int value); 36 | 37 | // Remove the item at the end of the array, and return it. 38 | std::optional pop_back(); 39 | 40 | // Update the item at the given position in the array. 41 | void update(int index, int value); 42 | 43 | // Get the item at the given position. 44 | std::optional get(int index) const; 45 | 46 | // Insert the new item in the given position. 47 | void insert(int index, int value); 48 | 49 | // Delete the item from the given position. 50 | void remove(int index); 51 | 52 | // Return the index of the first item. 53 | std::optional find(int value) const; 54 | }; 55 | 56 | } // namespace mf 57 | 58 | #endif // DYNAMIC_ARRAY_H 59 | -------------------------------------------------------------------------------- /data-structures/arrays/java/DynamicArray.java: -------------------------------------------------------------------------------- 1 | 2 | public class DynamicArray { 3 | private int capacity; 4 | private int size; 5 | private Object[] array; 6 | 7 | public DynamicArray() { 8 | this.capacity = 16; 9 | this.size = 0; 10 | this.array = new Object[this.capacity]; 11 | } 12 | 13 | public DynamicArray(int capacity) { 14 | this.capacity = capacity; 15 | this.size = 0; 16 | this.array = new Object[this.capacity]; 17 | } 18 | 19 | private void resize() { 20 | int newCapacity = this.capacity * 2; 21 | Object[] newArray = new Object[newCapacity]; 22 | System.arraycopy(this.array, 0, newArray, 0, this.size); 23 | 24 | this.array = newArray; 25 | this.capacity = newCapacity; 26 | } 27 | 28 | public void pushBack(Object element) { 29 | if (this.size >= this.capacity) { 30 | this.resize(); 31 | } 32 | this.array[this.size++] = element; 33 | } 34 | 35 | public Object popBack() throws Exception { 36 | if (this.size <= 0) { 37 | throw new Exception("DynamicArray is empty"); 38 | } 39 | return this.array[--this.size]; 40 | } 41 | 42 | public Object get(int index) throws Exception { 43 | if (index < 0 || index >= this.size) { 44 | throw new Exception("Index out of range"); 45 | } 46 | return this.array[index]; 47 | } 48 | 49 | public void set(Object element, int index) throws Exception { 50 | if (index < 0 || index >= this.size) { 51 | throw new Exception("Index out of range"); 52 | } 53 | this.array[index] = element; 54 | } 55 | 56 | public void insert(Object element, int index) throws Exception { 57 | if (index < 0 || index >= this.size) { 58 | throw new Exception("Index out of range"); 59 | } 60 | 61 | if (this.size >= this.capacity) { 62 | this.resize(); 63 | } 64 | 65 | for (int i = this.size - 1; i >= index; i--) { 66 | this.array[i + 1] = this.array[i]; 67 | } 68 | 69 | this.array[index] = element; 70 | this.size++; 71 | } 72 | 73 | public void delete(int index) throws Exception { 74 | if (index < 0 || index >= this.size) { 75 | throw new Exception("Index out of range"); 76 | } 77 | for (int i = index; i < this.size; i++) { 78 | this.array[i] = this.array[i + 1]; 79 | } 80 | this.size--; 81 | } 82 | 83 | public int find(Object element) throws Exception { 84 | for (int i = 0; i < this.size; i++) { 85 | if (this.array[i] == element) { 86 | return i; 87 | } 88 | } 89 | throw new Exception("Element does not exist"); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /data-structures/arrays/python/dynamic_array.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/evn python2 2 | # Python has a built-in implementation of the dynamic array named 'list'. 3 | 4 | def main(): 5 | dynamic_array = [] 6 | 7 | # Add an item to the end of the list. 8 | dynamic_array.append(1) 9 | dynamic_array.append(2) 10 | 11 | # Insert an item at a given position. 12 | dynamic_array.insert(0, 3) 13 | 14 | # Remove the item at the given position in the list, and return it. 15 | dynamic_array.pop() # Returns 2 16 | 17 | # Return the index in the list of the first item whose value is 3. 18 | dynamic_array.index(3) # Returns 0 19 | 20 | # Sort the items of the list in place. 21 | dynamic_array.sort() 22 | 23 | print dynamic_array 24 | 25 | 26 | if __name__ == '__main__': 27 | main() -------------------------------------------------------------------------------- /data-structures/binary_search_tree/c/binary_search_tree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "binary_search_tree.h" 6 | 7 | #define max(a, b) ((a) > (b) ? (a) : (b)) 8 | #define min(a, b) ((a) < (b) ? (a) : (b)) 9 | 10 | binary_tree_node_t *create_binary_tree(int value) 11 | { 12 | binary_tree_node_t *root = (binary_tree_node_t *)malloc(sizeof(binary_tree_node_t)); 13 | if (root == NULL) { 14 | exit(EXIT_FAILURE); 15 | } 16 | root->value = value; 17 | root->parent = NULL; 18 | root->left = NULL; 19 | root->right = NULL; 20 | return root; 21 | } 22 | 23 | static binary_tree_node_t *add_left_child(binary_tree_node_t *node, int value) 24 | { 25 | node->left = (binary_tree_node_t *)malloc(sizeof(binary_tree_node_t)); 26 | if (node->left == NULL) { 27 | return NULL; 28 | } 29 | node->left->value = value; 30 | node->left->parent = node; 31 | node->left->left = NULL; 32 | node->left->right = NULL; 33 | return node->left; 34 | } 35 | 36 | static binary_tree_node_t *add_right_child(binary_tree_node_t *node, int value) 37 | { 38 | node->right = (binary_tree_node_t *)malloc(sizeof(binary_tree_node_t)); 39 | if (node->right == NULL) { 40 | return NULL; 41 | } 42 | node->right->value = value; 43 | node->right->parent = node; 44 | node->right->left = NULL; 45 | node->right->right = NULL; 46 | return node->right; 47 | } 48 | 49 | void insert(binary_tree_node_t *node, int value) 50 | { 51 | binary_tree_node_t *curr = node; 52 | 53 | while (curr->value > value && curr->left != NULL || 54 | curr->value < value && curr->right != NULL) { 55 | if (curr->value > value) 56 | curr = curr->left; 57 | else 58 | curr = curr->right; 59 | } 60 | 61 | if (curr->value > value) 62 | add_left_child(curr, value); 63 | else if (curr->value < value) 64 | add_right_child(curr, value); 65 | else return; /* If they're the same, do nothing */ 66 | } 67 | 68 | binary_tree_node_t *find(binary_tree_node_t *node, int value) 69 | { 70 | while (node != NULL) { 71 | if (node->value == value) 72 | return node; 73 | 74 | if (node->value > value) 75 | node = node->left; 76 | else if (node->value < value) 77 | node = node->right; 78 | } 79 | return NULL; 80 | } 81 | 82 | void delete(binary_tree_node_t *node, int value) 83 | { 84 | binary_tree_node_t *curr = find(node, value); 85 | if (curr == NULL) 86 | return; 87 | 88 | /* The node doesn't have any children. */ 89 | if (curr->left == NULL && curr->right == NULL) { 90 | if (curr->parent->left == curr) 91 | curr->parent->left = NULL; 92 | else 93 | curr->parent->right = NULL; 94 | 95 | free(curr); 96 | return; 97 | } 98 | 99 | /* The node has only a left children. */ 100 | if (curr->right == NULL) { 101 | curr->left->parent = curr->parent; 102 | 103 | if (curr->parent->left == curr) 104 | curr->parent->left = curr->left; 105 | else 106 | curr->parent->right = curr->left; 107 | 108 | free(curr); 109 | return; 110 | } 111 | 112 | /* The node has only a right children. */ 113 | if (curr->left == NULL) { 114 | curr->right->parent = curr->parent; 115 | 116 | if (curr->parent->left == curr) 117 | curr->parent->left = curr->right; 118 | else 119 | curr->parent->right = curr->right; 120 | 121 | free(curr); 122 | return; 123 | } 124 | 125 | /* The node has two children. */ 126 | /* Now we're looking for the smallest value in the right subtree. */ 127 | binary_tree_node_t *smallest = curr->right; 128 | 129 | while (smallest->left != NULL) { 130 | smallest = smallest->left; 131 | } 132 | 133 | curr->value = smallest->value; 134 | return delete(smallest, smallest->value); 135 | } 136 | 137 | int height(binary_tree_node_t *node) 138 | { 139 | if (node == NULL) 140 | return -1; 141 | return 1 + max(height(node->left), height(node->right)); 142 | } 143 | 144 | int min_height(binary_tree_node_t *node) 145 | { 146 | if (node == NULL) 147 | return -1; 148 | return 1 + min(min_height(node->left), min_height(node->right)); 149 | } 150 | 151 | int nodes_with_one_child(binary_tree_node_t *node) 152 | { 153 | if (node == NULL) 154 | return 0; 155 | if (node->left == NULL ^ node->right == NULL) 156 | return 1; 157 | return nodes_with_one_child(node->left) + 158 | nodes_with_one_child(node->right); 159 | } 160 | 161 | binary_tree_node_t *maximum(binary_tree_node_t *node) 162 | { 163 | if (node == NULL) 164 | return NULL; 165 | 166 | while (node->right != NULL) 167 | node = node->right; 168 | return node; 169 | } 170 | 171 | binary_tree_node_t *minimum(binary_tree_node_t *node) 172 | { 173 | if (node == NULL) 174 | return NULL; 175 | 176 | while (node->left != NULL) 177 | node = node->left; 178 | return node; 179 | } 180 | 181 | int count(binary_tree_node_t *node) 182 | { 183 | if (node == NULL) 184 | return 0; 185 | return 1 + count(node->left) + count(node->right); 186 | } 187 | 188 | int leaf(binary_tree_node_t *node) 189 | { 190 | if (node == NULL) 191 | return 0; 192 | if (node->left == NULL && node->left == NULL) 193 | return 1; 194 | return leaf(node->left) + leaf(node->right); 195 | } 196 | 197 | bool is_between(binary_tree_node_t *node, int min, int max) 198 | { 199 | if (node == NULL) 200 | return true; 201 | 202 | return (node->value > min && node->value < max && 203 | is_between(node->left, min, node->value) && 204 | is_between(node->right, node->value, max)); 205 | } 206 | 207 | /* 208 | We can also use the in-order traversal and check each time 209 | that incoming data is sorted or not. 210 | */ 211 | bool is_binary_search_tree(binary_tree_node_t *root) 212 | { 213 | return is_between(root, INT_MIN, INT_MAX); 214 | } 215 | 216 | binary_tree_node_t *successor(binary_tree_node_t *root, int value) 217 | { 218 | binary_tree_node_t *node = find(root, value); 219 | if (node == NULL) 220 | return NULL; 221 | 222 | /* The node has a right subtree. */ 223 | if (node->right != NULL) 224 | return minimum(node->right); 225 | 226 | /* The node doesn't have a right subtree. */ 227 | binary_tree_node_t *parent = node->parent; 228 | while (parent != NULL && node == parent->right) { 229 | node = parent; 230 | parent = parent->parent; 231 | } 232 | return parent; 233 | } 234 | 235 | binary_tree_node_t *predecessor(binary_tree_node_t *root, int value) 236 | { 237 | binary_tree_node_t *node = find(root, value); 238 | if (node == NULL) 239 | return NULL; 240 | 241 | /* The node has a left subtree. */ 242 | if (node->left != NULL) 243 | return maximum(node->left); 244 | 245 | /* The node doesn't have a left subtree. */ 246 | binary_tree_node_t *parent = node->parent; 247 | while (parent != NULL && node == node->left) { 248 | node = parent; 249 | parent = parent->parent; 250 | } 251 | return parent; 252 | } 253 | -------------------------------------------------------------------------------- /data-structures/binary_search_tree/c/binary_search_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARY_SEARCH_TREE_H 2 | #define BINARY_SEARCH_TREE_H 3 | 4 | #include 5 | 6 | typedef struct binary_tree_node 7 | { 8 | int value; 9 | struct binary_tree_node *parent; 10 | struct binary_tree_node *left; 11 | struct binary_tree_node *right; 12 | } binary_tree_node_t; 13 | 14 | binary_tree_node_t *create_binary_tree(int value); 15 | 16 | static binary_tree_node_t *add_left_child(binary_tree_node_t *node, int value); 17 | 18 | static binary_tree_node_t *add_right_child(binary_tree_node_t *node, int value); 19 | 20 | void insert(binary_tree_node_t *node, int value); 21 | 22 | binary_tree_node_t *find(binary_tree_node_t *node, int value); 23 | 24 | int height(binary_tree_node_t *node); 25 | 26 | int min_height(binary_tree_node_t *node); 27 | 28 | int nodes_with_one_child(binary_tree_node_t *node); 29 | 30 | binary_tree_node_t *maximum(binary_tree_node_t *node); 31 | 32 | binary_tree_node_t *minimum(binary_tree_node_t *node); 33 | 34 | int count(binary_tree_node_t *node); 35 | 36 | int leaf(binary_tree_node_t *node); 37 | 38 | bool is_binary_search_tree(binary_tree_node_t *root); 39 | 40 | binary_tree_node_t *successor(binary_tree_node_t *root, int value); 41 | 42 | binary_tree_node_t *predecessor(binary_tree_node_t *root, int value); 43 | 44 | #endif // BINARY_SEARCH_TREE_H 45 | -------------------------------------------------------------------------------- /data-structures/binary_search_tree/cc/binary_search_tree.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "binary_search_tree.h" 4 | 5 | namespace mf 6 | { 7 | 8 | template 9 | BinarySearchTreeNode *BinarySearchTreeNode::add_left_child(const T& value) 10 | { 11 | left_ = new BinarySearchTreeNode(value, this); 12 | return left_; 13 | } 14 | 15 | template 16 | BinarySearchTreeNode *BinarySearchTreeNode::add_right_child(const T& value) 17 | { 18 | right_ = new BinarySearchTreeNode(value, this); 19 | return right_; 20 | } 21 | 22 | template 23 | void BinarySearchTree::insert(const T& value) 24 | { 25 | BinarySearchTreeNode *curr = root_; 26 | 27 | while (curr->value_ > value && curr->left_ != nullptr || 28 | curr->value_ < value && curr->right_ != nullptr) { 29 | if (curr->value_ > value) 30 | curr = curr->left_; 31 | else 32 | curr = curr->right_; 33 | } 34 | 35 | if (curr->value_ > value) 36 | curr->add_left_child(value); 37 | else if (curr->value_ < value) 38 | curr->add_right_child(value); 39 | else return; /* If they're the same, do nothing */ 40 | } 41 | 42 | template 43 | BinarySearchTreeNode *BinarySearchTree::find(BinarySearchTreeNode *node, 44 | const T& value) const 45 | { 46 | while (node != nullptr) { 47 | if (node->value_ == value) 48 | return node; 49 | else if (node->value_ > value) 50 | node = node->left_; 51 | else 52 | node = node->right_; 53 | } 54 | return nullptr; 55 | } 56 | 57 | template 58 | void BinarySearchTree::remove(BinarySearchTreeNode *node, const T& value) 59 | { 60 | BinarySearchTreeNode *curr = this->find(node, value); 61 | if (curr == nullptr) 62 | return; 63 | 64 | /* The node doesn't have any children. */ 65 | if (curr->left_ == nullptr && curr->right_ == nullptr) { 66 | if (curr->parent_->left_ == curr) 67 | curr->parent_->left_ = nullptr; 68 | else 69 | curr->parent_->right_ = nullptr; 70 | 71 | delete curr; 72 | return; 73 | } 74 | 75 | /* The node has only a left children. */ 76 | if (curr->right_ == nullptr) { 77 | curr->left_->parent_ = curr->parent_; 78 | 79 | if (curr->parent_->left_ == curr) 80 | curr->parent_->left_ = curr->left_; 81 | else 82 | curr->parent_->right_ = curr->left_; 83 | 84 | delete curr; 85 | return; 86 | } 87 | 88 | /* The node has only a right children. */ 89 | if (curr->left_ == nullptr) { 90 | curr->right_->parent_ = curr->parent_; 91 | 92 | if (curr->parent_->left_ == curr) 93 | curr->parent_->left_ = curr->right_; 94 | else 95 | curr->parent_->right_ = curr->right_; 96 | 97 | delete curr; 98 | return; 99 | } 100 | 101 | /* The node has two children. */ 102 | /* Now we're looking for the smallest value in the right subtree. */ 103 | BinarySearchTreeNode *smallest = curr->right_; 104 | 105 | while (smallest->left_ != nullptr) { 106 | smallest = smallest->left_; 107 | } 108 | 109 | curr->value_ = smallest->value_; 110 | return remove(smallest, smallest->value_); 111 | } 112 | 113 | template 114 | int BinarySearchTree::height(BinarySearchTreeNode *node) 115 | { 116 | if (node == nullptr) 117 | return -1; 118 | return 1 + std::max(height(node->left_), height(node->right_)); 119 | } 120 | 121 | template 122 | int BinarySearchTree::min_height(BinarySearchTreeNode *node) 123 | { 124 | if (node == nullptr) 125 | return -1; 126 | return 1 + std::min(min_height(node->left_), min_height(node->right_)); 127 | } 128 | 129 | template 130 | int BinarySearchTree::nodes_with_one_child(BinarySearchTreeNode *node) 131 | { 132 | if (node == nullptr) 133 | return 0; 134 | if (node->left_ == nullptr ^ node->right_ == nullptr) 135 | return 1; 136 | return nodes_with_one_child(node->left_) + nodes_with_one_child(node->right_); 137 | } 138 | 139 | template 140 | int BinarySearchTree::count(BinarySearchTreeNode *node) 141 | { 142 | if (node == nullptr) 143 | return 0; 144 | return 1 + count(node->left_) + count(node->right_); 145 | } 146 | 147 | template 148 | BinarySearchTreeNode *BinarySearchTree::maximum() const 149 | { 150 | BinarySearchTreeNode *curr = root_; 151 | while (curr->right_ != nullptr) 152 | curr = curr->right_; 153 | return curr; 154 | } 155 | 156 | template 157 | BinarySearchTreeNode *BinarySearchTree::minimum() const 158 | { 159 | BinarySearchTreeNode *curr = root_; 160 | while (curr->left_ != nullptr) 161 | curr = curr->left_; 162 | return curr; 163 | } 164 | 165 | template 166 | int BinarySearchTree::leaf(BinarySearchTreeNode *node) 167 | { 168 | if (node == nullptr) 169 | return 0; 170 | if (node->left_ == nullptr && node->right_ == nullptr) 171 | return 1; 172 | return leaf(node->left_) + leaf(node->right_); 173 | } 174 | 175 | template 176 | bool BinarySearchTree::is_between(BinarySearchTreeNode *node, 177 | int min, int max) 178 | { 179 | if (node == nullptr) 180 | return true; 181 | return (node->value_ > min && node->value_ < max && 182 | is_between(node->left_, min, node->value_) && 183 | is_between(node->right_, node->value_, max)); 184 | } 185 | 186 | /* 187 | We can also use the in-order traversal and check each time 188 | that incoming data is sorted or not. 189 | */ 190 | template 191 | bool BinarySearchTree::is_binary_search_tree() 192 | { 193 | return is_between(root_, std::numeric_limits::min(), 194 | std::numeric_limits::max()); 195 | } 196 | 197 | template 198 | BinarySearchTreeNode *BinarySearchTree::successor(const T& value) const 199 | { 200 | BinarySearchTreeNode *node = find(value); 201 | if (node == nullptr) 202 | return nullptr; 203 | 204 | /* The node has a right subtree. */ 205 | if (node->right_ != nullptr) { 206 | BinarySearchTreeNode *curr = node->right_; 207 | while (curr->left_ != nullptr) 208 | curr = curr->left_; 209 | return curr; 210 | } 211 | 212 | /* The node doesn't have a right subtree. */ 213 | BinarySearchTreeNode *parent = node->parent_; 214 | while (parent != nullptr && node == parent->right_) { 215 | node = parent; 216 | parent = parent->parent_; 217 | } 218 | return parent; 219 | } 220 | 221 | template 222 | BinarySearchTreeNode *BinarySearchTree::predecessor(const T& value) const 223 | { 224 | BinarySearchTreeNode *node = find(value); 225 | if (node == nullptr) 226 | return nullptr; 227 | 228 | /* The node has a left subtree. */ 229 | if (node->left_ != nullptr) { 230 | BinarySearchTreeNode *curr = node->left_; 231 | while (curr->right_ != nullptr) 232 | curr = curr->right_; 233 | return curr; 234 | } 235 | 236 | /* The node doesn't have a left subtree. */ 237 | BinarySearchTreeNode *parent = node->parent_; 238 | while (parent != nullptr && node == parent->left_) { 239 | node = parent; 240 | parent = parent->parent_; 241 | } 242 | return parent; 243 | } 244 | 245 | } // namespace mf 246 | -------------------------------------------------------------------------------- /data-structures/binary_search_tree/cc/binary_search_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARY_SEARCH_TREE_H 2 | #define BINARY_SEARCH_TREE_H 3 | 4 | namespace mf 5 | { 6 | /* Used for the friend relationship between BinarySearchTree and BinarySearchTreeNode */ 7 | template class BinarySearchTree; 8 | 9 | template 10 | class BinarySearchTreeNode 11 | { 12 | private: 13 | T value_; 14 | BinarySearchTreeNode *parent_; 15 | BinarySearchTreeNode *left_; 16 | BinarySearchTreeNode *right_; 17 | 18 | friend class BinarySearchTree; 19 | 20 | public: 21 | BinarySearchTreeNode(const T& value, BinarySearchTreeNode *parent) : value_(value), 22 | parent_(parent), left_(nullptr), right_(nullptr) {} 23 | ~BinarySearchTreeNode() {} 24 | 25 | BinarySearchTreeNode *add_left_child(const T& value); 26 | BinarySearchTreeNode *add_right_child(const T& value); 27 | }; 28 | 29 | template 30 | class BinarySearchTree 31 | { 32 | private: 33 | BinarySearchTreeNode *root_; 34 | int height(BinarySearchTreeNode *node); 35 | int min_height(BinarySearchTreeNode *node); 36 | int nodes_with_one_child(BinarySearchTreeNode *node); 37 | int count(BinarySearchTreeNode *node); 38 | int leaf(BinarySearchTreeNode *node); 39 | void remove(BinarySearchTreeNode *node, const T& value); 40 | bool is_between(BinarySearchTreeNode *node, int min, int max); 41 | BinarySearchTreeNode *find(BinarySearchTreeNode *node, const T& value) const; 42 | 43 | public: 44 | BinarySearchTree(const T& value) { root_ = new BinarySearchTreeNode(value, nullptr); } 45 | ~BinarySearchTree() {} 46 | 47 | void insert(const T& value); 48 | void remove(const T& value) { return remove(root_, value); } 49 | BinarySearchTreeNode *find(const T& value) const { return find(root_, value); }; 50 | 51 | int height() { return height(root_); } 52 | int min_height() { return min_height(root_); } 53 | int nodes_with_one_child() { return nodes_with_one_child(root_); } 54 | int count() { return count(root_); } 55 | int leaf() { return leaf(root_); } 56 | 57 | BinarySearchTreeNode *maximum() const; 58 | BinarySearchTreeNode *minimum() const; 59 | 60 | bool is_binary_search_tree(); 61 | BinarySearchTreeNode *successor(const T& value) const; 62 | BinarySearchTreeNode *predecessor(const T& value) const; 63 | }; 64 | 65 | } // namespace mf 66 | 67 | #endif // BINARY_SEARCH_TREE_H 68 | -------------------------------------------------------------------------------- /data-structures/binary_search_tree/python/binary_search_tree.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | 4 | class BinarySearchTreeNode(object): 5 | def __init__(self, value, parent): 6 | self.value = value 7 | self.parent = parent 8 | self.left = None 9 | self.right = None 10 | 11 | def add_left_child(self, value): 12 | self.left = BinarySearchTreeNode(value, self) 13 | 14 | def add_right_child(self, value): 15 | self.right = BinarySearchTreeNode(value, self) 16 | 17 | 18 | class BinarySearchTree(object): 19 | def __init__(self, value): 20 | self._root = BinarySearchTreeNode(value, None) 21 | 22 | def __len__(self): 23 | return self._count(self._root) 24 | 25 | def _count(self, node): 26 | if node is None: 27 | return 0 28 | return 1 + self._count(node.left) + self._count(node.right) 29 | 30 | def insert(self, value): 31 | curr = self._root 32 | while (curr.value > value and curr.left is not None) or \ 33 | (curr.value < value and curr.right is not None): 34 | if curr.value > value: 35 | curr = curr.left 36 | else: 37 | curr = curr.right 38 | 39 | if curr.value > value: 40 | curr.add_left_child(value) 41 | elif curr.value < value: 42 | curr.add_right_child(value) 43 | 44 | def _find(self, node, value): 45 | while node is not None: 46 | if node.value == value: 47 | return node 48 | elif node.value > value: 49 | node = node.left 50 | else: 51 | node = node.right 52 | return None 53 | 54 | def find(self, value): 55 | return self._find(self._root, value) 56 | 57 | def _delete(self, node, value): 58 | curr = self._find(node, value) 59 | if curr is None: 60 | return 61 | 62 | # The node doesn't have any children. 63 | if curr.left is None and curr.right is None: 64 | if curr.parent.left == curr: 65 | curr.parent.left = None 66 | else: 67 | curr.parent.right = None 68 | return 69 | 70 | # The node has only a left children. 71 | if curr.right is None: 72 | curr.left.parent = curr.parent 73 | if curr.parent.left == curr: 74 | curr.parent.left = curr.left 75 | else: 76 | curr.parent.right = curr.left 77 | return 78 | 79 | # The node has only a right children. 80 | if curr.left is None: 81 | curr.right.parent = curr.parent 82 | if curr.parent.left == curr: 83 | curr.parent.left = curr.right 84 | else: 85 | curr.parent.right = curr.right 86 | return 87 | 88 | # The node has two children. 89 | # Now we're looking for the smallest value in the right subtree. 90 | smallest = curr.right 91 | while smallest.left is not None: 92 | smallest = smallest.left 93 | 94 | curr.value = smallest.value 95 | return self._delete(smallest, smallest.value) 96 | 97 | def delete(self, value): 98 | return self._delete(self._root, value) 99 | 100 | def _height(self, node): 101 | if node is None: 102 | return -1 103 | return 1 + max(self._height(node.left), self._height(node.right)) 104 | 105 | @property 106 | def height(self): 107 | return self._height(self._root) 108 | 109 | def maximum(self, node): 110 | if node is None: 111 | return 112 | while node.right is not None: 113 | node = node.right 114 | return node 115 | 116 | def minimum(self, node): 117 | if node is None: 118 | return 119 | while node.left is not None: 120 | node = node.left 121 | return node 122 | 123 | def _is_binary_search_tree(self, node, min, max): 124 | if node is None: 125 | return True 126 | return node.value > min and node.value < max and \ 127 | self._is_binary_search_tree(node.left, min, node.value) and \ 128 | self._is_binary_search_tree(node.right, node.value, max) 129 | 130 | @property 131 | def is_binary_search_tree(self): 132 | # We can also use the in-order traversal and check each time 133 | # that incoming data is sorted or not. 134 | return self._is_binary_search_tree(self._root, float('-inf'), float('inf')) 135 | 136 | def successor(self, value): 137 | node = self._find(self._root, value) 138 | if node is None: 139 | return 140 | 141 | # The node has a right subtree. 142 | if node.right is not None: 143 | return self.minimum(node.right) 144 | 145 | # The node doesn't have a right subtree. 146 | parent = node.parent 147 | while parent is not None and node == parent.right: 148 | node = parent 149 | parent = parent.parent 150 | return parent 151 | 152 | def predecessor(self, value): 153 | node = self._find(self._root, value) 154 | if node is None: 155 | return 156 | 157 | # The node has a left subtree. 158 | if node.left is not None: 159 | return self.maximum(node.left) 160 | 161 | # The node doesn't have a left subtree. 162 | parent = node.parent 163 | while parent is not None and node == parent.left: 164 | node = parent 165 | parent = parent.parent 166 | return parent 167 | -------------------------------------------------------------------------------- /data-structures/binary_tree/c/binary_tree.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "binary_tree.h" 3 | 4 | binary_tree_node_t *create_binary_tree(int value) 5 | { 6 | binary_tree_node_t *root = (binary_tree_node_t *)malloc(sizeof(binary_tree_node_t)); 7 | if (root == NULL) { 8 | exit(EXIT_FAILURE); 9 | } 10 | root->value = value; 11 | root->parent = NULL; 12 | root->left = NULL; 13 | root->right = NULL; 14 | return root; 15 | } 16 | 17 | binary_tree_node_t *add_left_child(binary_tree_node_t *node, int value) 18 | { 19 | node->left = (binary_tree_node_t *)malloc(sizeof(binary_tree_node_t)); 20 | if (node->left == NULL) { 21 | return NULL; 22 | } 23 | node->left->value = value; 24 | node->left->parent = node; 25 | node->left->left = NULL; 26 | node->left->right = NULL; 27 | return node->left; 28 | } 29 | 30 | binary_tree_node_t *add_right_child(binary_tree_node_t *node, int value) 31 | { 32 | node->right = (binary_tree_node_t *)malloc(sizeof(binary_tree_node_t)); 33 | if (node->right == NULL) { 34 | return NULL; 35 | } 36 | node->right->value = value; 37 | node->right->parent = node; 38 | node->right->left = NULL; 39 | node->right->right = NULL; 40 | return node->right; 41 | } 42 | 43 | void pre_order(binary_tree_node_t *node) 44 | { 45 | if (node == NULL) 46 | return; 47 | 48 | printf("%i ", node->value); 49 | pre_order(node->left); 50 | pre_order(node->right); 51 | } 52 | 53 | void post_order(binary_tree_node_t *node) 54 | { 55 | if (node == NULL) 56 | return; 57 | 58 | post_order(node->left); 59 | post_order(node->right); 60 | printf("%i ", node->value); 61 | } 62 | 63 | void in_order(binary_tree_node_t *node) 64 | { 65 | if (node == NULL) 66 | return; 67 | 68 | in_order(node->left); 69 | printf("%i ", node->value); 70 | in_order(node->right); 71 | } 72 | 73 | void level_order(binary_tree_node_t *node) 74 | { 75 | queue_t *queue = create_queue(); 76 | enqueue(queue, node); 77 | 78 | while (queue->head != NULL) { 79 | binary_tree_node_t *current = dequeue(queue); 80 | 81 | if (current->left != NULL) 82 | enqueue(queue, current->left); 83 | 84 | if (current->right != NULL) 85 | enqueue(queue, current->right); 86 | 87 | printf("%i ", current->value); 88 | } 89 | remove_queue(queue); 90 | } 91 | 92 | 93 | int main(void) 94 | { 95 | binary_tree_node_t *root = create_binary_tree(1); 96 | binary_tree_node_t *left = NULL; 97 | binary_tree_node_t *right = NULL; 98 | binary_tree_node_t *left2 = NULL; 99 | 100 | left = add_left_child(root, 2); 101 | right = add_right_child(root, 3); 102 | 103 | left2 = add_left_child(left, 4); 104 | add_right_child(left, 5); 105 | 106 | add_left_child(right, 6); 107 | add_right_child(right, 7); 108 | 109 | add_left_child(left2, 8); 110 | add_right_child(left2, 9); 111 | 112 | level_order(root); 113 | 114 | return 0; 115 | } -------------------------------------------------------------------------------- /data-structures/binary_tree/c/binary_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARY_TREE_H 2 | #define BINARY_TREE_H 3 | 4 | #include 5 | 6 | typedef struct binary_tree_node 7 | { 8 | int value; 9 | struct binary_tree_node *parent; 10 | struct binary_tree_node *left; 11 | struct binary_tree_node *right; 12 | } binary_tree_node_t; 13 | 14 | binary_tree_node_t *create_binary_tree(int value); 15 | 16 | binary_tree_node_t *add_left_child(binary_tree_node_t *node, int value); 17 | 18 | binary_tree_node_t *add_right_child(binary_tree_node_t *node, int value); 19 | 20 | /* Depth-first search */ 21 | void pre_order(binary_tree_node_t *node); 22 | 23 | /* Depth-first search */ 24 | void post_order(binary_tree_node_t *node); 25 | 26 | /* Depth-first search */ 27 | void in_order(binary_tree_node_t *node); 28 | 29 | /* Breadth-first search */ 30 | void level_order(binary_tree_node_t *node); 31 | 32 | /* Implementation of queue using the linked list structure below */ 33 | /* The queue is used to help us go through the tree by using the level order traversal */ 34 | 35 | typedef struct queue_node 36 | { 37 | binary_tree_node_t *item; 38 | struct queue_node *next; 39 | } queue_node_t; 40 | 41 | typedef struct queue 42 | { 43 | queue_node_t *head; 44 | queue_node_t *tail; 45 | } queue_t; 46 | 47 | queue_t *create_queue(void); 48 | 49 | void remove_queue(queue_t *queue) 50 | { 51 | queue_node_t *current = queue->head; 52 | queue_node_t *next; 53 | while (current != NULL) { 54 | next = current->next; 55 | free(current); 56 | current = next; 57 | } 58 | free(queue); 59 | } 60 | 61 | void enqueue(queue_t *queue, binary_tree_node_t *item); 62 | 63 | binary_tree_node_t *dequeue(queue_t *queue); 64 | 65 | queue_t *create_queue(void) 66 | { 67 | queue_t *queue = (queue_t *)malloc(sizeof(queue_t)); 68 | if (queue == NULL) 69 | exit(EXIT_FAILURE); 70 | 71 | queue->head = NULL; 72 | queue->tail = NULL; 73 | return queue; 74 | } 75 | 76 | void enqueue(queue_t *queue, binary_tree_node_t *item) 77 | { 78 | queue_node_t *node = (queue_node_t *)malloc(sizeof(queue_node_t)); 79 | if (node == NULL) 80 | return; 81 | node->item = item; 82 | node->next = NULL; 83 | 84 | if (queue->head == NULL) 85 | queue->head = node; 86 | else 87 | queue->tail->next = node; 88 | 89 | queue->tail = node; 90 | } 91 | 92 | binary_tree_node_t *dequeue(queue_t *queue) 93 | { 94 | if (queue->head == NULL) 95 | return NULL; // The queue is empty. 96 | 97 | queue_node_t *node = queue->head; 98 | binary_tree_node_t *item = node->item; 99 | 100 | queue->head = queue->head->next; 101 | if (queue->head == NULL) 102 | queue->tail = NULL; 103 | 104 | free(node); 105 | return item; 106 | } 107 | 108 | #endif // BINARY_TREE_H 109 | -------------------------------------------------------------------------------- /data-structures/binary_tree/cc/binary_tree.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "binary_tree.h" 3 | #include "queue_linked_list.h" 4 | 5 | namespace mf 6 | { 7 | 8 | template 9 | BinaryTreeNode *BinaryTreeNode::add_left_child(const T &value) 10 | { 11 | left_ = new BinaryTreeNode(value, this); 12 | return left_; 13 | } 14 | 15 | template 16 | BinaryTreeNode *BinaryTreeNode::add_right_child(const T &value) 17 | { 18 | right_ = new BinaryTreeNode(value, this); 19 | return right_; 20 | } 21 | 22 | template 23 | void BinaryTree::pre_order(BinaryTreeNode *node) 24 | { 25 | if (node == nullptr) 26 | return; 27 | 28 | std::cout << node->value_ << " "; 29 | pre_order(node->left_); 30 | pre_order(node->right_); 31 | } 32 | 33 | template 34 | void BinaryTree::post_order(BinaryTreeNode *node) 35 | { 36 | if (node == nullptr) 37 | return; 38 | 39 | post_order(node->left_); 40 | post_order(node->right_); 41 | std::cout << node->value_ << " "; 42 | } 43 | 44 | template 45 | void BinaryTree::in_order(BinaryTreeNode *node) 46 | { 47 | if (node == nullptr) 48 | return; 49 | 50 | in_order(node->left_); 51 | std::cout << node->value_ << " "; 52 | in_order(node->right_); 53 | } 54 | 55 | template 56 | void BinaryTree::level_order() 57 | { 58 | Queue *> queue; 59 | BinaryTreeNode *current; 60 | 61 | queue.enqueue(root_); 62 | 63 | while (!queue.is_empty()) { 64 | current = queue.dequeue(); 65 | 66 | if (current->left_ != nullptr) 67 | queue.enqueue(current->left_); 68 | 69 | if (current->right_ != nullptr) 70 | queue.enqueue(current->right_); 71 | 72 | std::cout << current->value_ << " "; 73 | } 74 | } 75 | 76 | } // namespace mf 77 | -------------------------------------------------------------------------------- /data-structures/binary_tree/cc/binary_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef BINARY_TREE_H 2 | #define BINARY_TREE_H 3 | 4 | namespace mf 5 | { 6 | /* Used for the friend relationship between BinaryTree and BinaryTreeNode */ 7 | template class BinaryTree; 8 | 9 | template 10 | class BinaryTreeNode 11 | { 12 | private: 13 | T value_; 14 | BinaryTreeNode *parent_; 15 | BinaryTreeNode *left_; 16 | BinaryTreeNode *right_; 17 | 18 | friend class BinaryTree; 19 | 20 | public: 21 | BinaryTreeNode(const T& value, BinaryTreeNode *parent) : value_(value), 22 | parent_(parent), left_(nullptr), right_(nullptr) {} 23 | ~BinaryTreeNode() {} 24 | 25 | BinaryTreeNode *add_left_child(const T &value); 26 | BinaryTreeNode *add_right_child(const T &value); 27 | }; 28 | 29 | template 30 | class BinaryTree 31 | { 32 | private: 33 | BinaryTreeNode *root_; 34 | 35 | /* Depth-first search */ 36 | void pre_order(BinaryTreeNode *node); 37 | void post_order(BinaryTreeNode *node); 38 | void in_order(BinaryTreeNode *node); 39 | 40 | public: 41 | BinaryTree(const T &value) { root_ = new BinaryTreeNode(value, nullptr); } 42 | BinaryTreeNode *get_root() const { return root_; } 43 | 44 | /* Depth-first search */ 45 | void pre_order() { pre_order(root_); } 46 | void post_order() { post_order(root_); } 47 | void in_order() { in_order(root_); } 48 | 49 | /* Breadth-first search */ 50 | void level_order(); 51 | }; 52 | 53 | } // namespace mf 54 | 55 | #endif // BINARY_TREE_H 56 | -------------------------------------------------------------------------------- /data-structures/binary_tree/cc/queue_linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_LINKED_LIST_H 2 | #define QUEUE_LINKED_LIST_H 3 | 4 | template 5 | class QueueNode 6 | { 7 | private: 8 | T value_; 9 | QueueNode *next_; 10 | 11 | public: 12 | QueueNode(const T &value) : value_(value), next_(nullptr) {} 13 | ~QueueNode() {} 14 | 15 | const T &get_value() const { return value_; } 16 | QueueNode *get_next() const { return next_; } 17 | 18 | void set_value(const T &value) { value_ = value; } 19 | void set_next(QueueNode *next) { next_ = next; } 20 | }; 21 | 22 | template 23 | class Queue 24 | { 25 | private: 26 | QueueNode *head_; 27 | QueueNode *tail_; 28 | 29 | public: 30 | Queue() : head_(nullptr), tail_(nullptr) {} 31 | ~Queue(); 32 | 33 | void enqueue(T value); 34 | const T dequeue(); 35 | bool is_empty() const; 36 | }; 37 | 38 | #endif // QUEUE_LINKED_LIST_H 39 | 40 | /* Source */ 41 | 42 | template 43 | Queue::~Queue() 44 | { 45 | QueueNode *current = head_; 46 | QueueNode *next = nullptr; 47 | 48 | while (current != nullptr) { 49 | next = current->get_next(); 50 | delete current; 51 | current = next; 52 | } 53 | } 54 | 55 | template 56 | void Queue::enqueue(T value) 57 | { 58 | QueueNode *node = new QueueNode(value); 59 | node->set_next(nullptr); 60 | 61 | if (head_ == nullptr) 62 | head_ = node; 63 | else 64 | tail_->set_next(node); 65 | 66 | tail_ = node; 67 | } 68 | 69 | template 70 | const T Queue::dequeue() 71 | { 72 | QueueNode *node = head_; 73 | T value = node->get_value(); 74 | 75 | head_ = head_->get_next(); 76 | if (head_ == nullptr) 77 | tail_ = nullptr; 78 | 79 | delete node; 80 | return value; 81 | } 82 | 83 | template 84 | bool Queue::is_empty() const 85 | { 86 | return head_ == nullptr; 87 | } 88 | -------------------------------------------------------------------------------- /data-structures/binary_tree/python/binary_tree.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | from collections import deque 4 | 5 | 6 | class BinaryTreeNode(object): 7 | def __init__(self, value=None, parent=None): 8 | self._parent = parent 9 | self._value = value 10 | self._left = None 11 | self._right = None 12 | 13 | def add_left_child(self, value): 14 | self._left = BinaryTreeNode(value, self) 15 | return self._left 16 | 17 | def add_right_child(self, value): 18 | self._right = BinaryTreeNode(value, self) 19 | return self._right 20 | 21 | @property 22 | def left(self): 23 | return self._left 24 | 25 | @property 26 | def right(self): 27 | return self._right 28 | 29 | @property 30 | def value(self): 31 | return self._value 32 | 33 | 34 | class BinaryTree(object): 35 | def __init__(self, value): 36 | self._root = BinaryTreeNode(value, None) 37 | 38 | @property 39 | def root(self): 40 | return self._root 41 | 42 | def _pre_order(self, node): 43 | """Depth-first search""" 44 | if node is None: 45 | return 46 | 47 | print node.value, 48 | self._pre_order(node.left) 49 | self._pre_order(node.right) 50 | 51 | def pre_order(self): 52 | """Depth-first search""" 53 | self._pre_order(self._root) 54 | 55 | def _post_order(self, node): 56 | """Depth-first search""" 57 | if node is None: 58 | return 59 | 60 | self._post_order(node.left) 61 | self._post_order(node.right) 62 | print node.value, 63 | 64 | def post_order(self): 65 | """Depth-first search""" 66 | self._post_order(self._root) 67 | 68 | def _in_order(self, node): 69 | """Depth-first search""" 70 | if node is None: 71 | return 72 | 73 | self._in_order(node.left) 74 | print node.value, 75 | self._in_order(node.right) 76 | 77 | def in_order(self): 78 | """Depth-first search""" 79 | self._in_order(self._root) 80 | 81 | def level_order(self): 82 | """Breadth-first search""" 83 | queue = deque() 84 | queue.append(self._root) 85 | 86 | while len(queue) > 0: 87 | node = queue.popleft() 88 | 89 | if node.left is not None: 90 | queue.append(node.left) 91 | 92 | if node.right is not None: 93 | queue.append(node.right) 94 | 95 | print node.value, 96 | -------------------------------------------------------------------------------- /data-structures/graph/c/graph_adjacency_lists.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "graph_adjacency_lists.h" 5 | 6 | graph_t *create_graph(int vertices) 7 | { 8 | graph_t *graph = (graph_t *)malloc(sizeof(graph_t)); 9 | if (graph == NULL) 10 | exit(EXIT_FAILURE); 11 | graph->edges = 0; 12 | graph->vertices = vertices; 13 | graph->lists = (linked_list_t **)malloc(sizeof(linked_list_t *) * graph->vertices); 14 | if (graph->lists == NULL) 15 | exit(EXIT_FAILURE); 16 | for (int i = 0; i < graph->vertices; i++) 17 | graph->lists[i] = create_linked_list(); 18 | return graph; 19 | } 20 | 21 | void remove_graph(graph_t *g) 22 | { 23 | assert(g != NULL && g->lists != NULL); 24 | for (int i = 0; i < g->vertices; i++) 25 | remove_linked_list(g->lists[i]); 26 | free(g); 27 | } 28 | 29 | void add_edge(graph_t *g, int src, int dest) 30 | { 31 | if (src < 0 || dest < 0 || src >= g->vertices || dest >= g->vertices) 32 | return; 33 | push_back(g->lists[src], dest); 34 | g->edges++; 35 | } 36 | 37 | void remove_edge(graph_t *g, int src, int dest) 38 | { 39 | if (src < 0 || dest < 0 || src >= g->vertices || dest >= g->vertices) 40 | return; 41 | erase(g->lists[src], dest); 42 | g->edges--; 43 | } 44 | 45 | void breadth_first_search(graph_t *g, int vertex) 46 | { 47 | bool visited[g->vertices]; 48 | memset(visited, false, sizeof(bool) * g->vertices); 49 | queue_t *q = create_queue(g->vertices); 50 | 51 | visited[vertex] = true; 52 | enqueue(q, vertex); 53 | 54 | while (!empty_queue(q)) { 55 | int v = dequeue(q); 56 | /* Do whatever with the vertex. We'll just print its value. */ 57 | printf("%i ", v); 58 | linked_list_node_t *current = g->lists[v]->head; 59 | while (current != NULL) { 60 | if (visited[current->value] == false) { 61 | visited[current->value] = true; 62 | enqueue(q, current->value); 63 | } 64 | current = current->next; 65 | } 66 | } 67 | remove_queue(q); 68 | } 69 | 70 | static void depth_first_search_(graph_t *g, int vertex, bool visited[]) 71 | { 72 | visited[vertex] = true; 73 | /* Do whatever with the vertex. We'll just print its value. */ 74 | printf("%i ", vertex); 75 | linked_list_node_t *current = g->lists[vertex]->head; 76 | while (current != NULL) { 77 | if (visited[current->value] == false) 78 | depth_first_search_(g, current->value, visited); 79 | current = current->next; 80 | } 81 | } 82 | 83 | void depth_first_search(graph_t *g, int vertex) 84 | { 85 | bool visited[g->vertices]; 86 | memset(visited, false, sizeof(bool) * g->vertices); 87 | depth_first_search_(g, vertex, visited); 88 | /* Visit all the vertices. 89 | (void)vertex; 90 | for (int v = 0; v < g->vertices && visited[v] == false; v++) 91 | depth_first_search_(g, v, visited); 92 | */ 93 | } 94 | 95 | void depth_first_search_iter(graph_t *g, int vertex) 96 | { 97 | bool visited[g->vertices]; 98 | memset(visited, false, sizeof(bool) * g->vertices); 99 | stack_t *s = create_stack(g->vertices); 100 | 101 | visited[vertex] = true; 102 | push(s, vertex); 103 | 104 | while (!empty_stack(s)) { 105 | int v = pop(s); 106 | /* Do whatever with the vertex. We'll just print its value. */ 107 | printf("%i ", v); 108 | linked_list_node_t *current = g->lists[v]->head; 109 | while (current != NULL) { 110 | if (visited[current->value] == false) { 111 | visited[current->value] = true; 112 | push(s, current->value); 113 | } 114 | current = current->next; 115 | } 116 | } 117 | remove_stack(s); 118 | } 119 | 120 | static bool find_path_(graph_t *g, int src, int dest, bool visited[], 121 | stack_t *s) 122 | { 123 | visited[src] = true; 124 | push(s, src); 125 | if (src == dest) return true; 126 | 127 | linked_list_node_t *current = g->lists[src]->head; 128 | while (current != NULL) { 129 | if (!visited[current->value] && find_path_(g, current->value, dest, visited, s)) 130 | return true; 131 | current = current->next; 132 | } 133 | pop(s); 134 | return false; 135 | } 136 | 137 | /* Finding a path between two vertices using the depth first search. */ 138 | void find_path(graph_t *g, int src, int dest) 139 | { 140 | if (src < 0 || dest < 0 || src >= g->vertices || dest >= g->vertices) 141 | return; 142 | bool visited[g->vertices]; 143 | memset(visited, false, sizeof(bool) * g->vertices); 144 | stack_t *s = create_stack(g->vertices); 145 | 146 | if (find_path_(g, src, dest, visited, s) == true) { 147 | while (!empty_stack(s)) 148 | printf("%i ", pop(s)); 149 | } else 150 | printf("The path doesn't exist.\n"); 151 | 152 | remove_stack(s); 153 | } 154 | 155 | /* Finding the shortest path between two vertices using the 156 | breadth first search. */ 157 | void find_shortest_path(graph_t *g, int src, int dest) 158 | { 159 | #define NOT_VISITED -2 160 | #define START_POINT -1 161 | if (src < 0 || dest < 0 || src >= g->vertices || dest >= g->vertices) 162 | return; 163 | int visited[g->vertices]; 164 | /* Initializate the array with a special value (-2) = not visited. */ 165 | for (int i = 0; i < g->vertices; i++) 166 | visited[i] = NOT_VISITED; 167 | 168 | queue_t *q = create_queue(g->vertices); 169 | int v; 170 | 171 | visited[src] = START_POINT; /* We mark the start point as (-1). */ 172 | enqueue(q, src); 173 | 174 | while (!empty_queue(q)) { 175 | v = dequeue(q); 176 | 177 | linked_list_node_t *current = g->lists[v]->head; 178 | while (current != NULL) { 179 | if (visited[current->value] == NOT_VISITED) { 180 | visited[current->value] = v; 181 | enqueue(q, current->value); 182 | /* Print the shortest path and we're done. */ 183 | if (current->value == dest) { 184 | v = current->value; 185 | while (v > START_POINT) { 186 | printf("%i ", v); 187 | v = visited[v]; 188 | } 189 | goto done; 190 | } 191 | } 192 | current = current->next; 193 | } 194 | } 195 | 196 | done: 197 | remove_queue(q); 198 | #undef NOT_VISITED 199 | #undef START_POINT 200 | } 201 | -------------------------------------------------------------------------------- /data-structures/graph/c/graph_adjacency_lists.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPH_ADJACENCY_LISTS_H 2 | #define GRAPH_ADJACENCY_LISTS_H 3 | 4 | #include 5 | #include "stack.h" 6 | #include "queue.h" 7 | #include "linked_list.h" 8 | 9 | typedef struct 10 | { 11 | int vertices; /* number of vertices */ 12 | int edges; /* number of edges */ 13 | linked_list_t **lists; 14 | } graph_t; 15 | 16 | graph_t *create_graph(int vertices); 17 | 18 | void remove_graph(graph_t *g); 19 | 20 | void add_edge(graph_t *g, int src, int dest); 21 | 22 | void remove_edge(graph_t *g, int src, int dest); 23 | 24 | void breadth_first_search(graph_t *g, int vertex); 25 | 26 | static void depth_first_search_(graph_t *g, int vertex, bool visited[]); 27 | 28 | void depth_first_search(graph_t *g, int vertex); 29 | 30 | static bool find_path_(graph_t *g, int src, int dest, bool visited[], 31 | stack_t *s); 32 | 33 | void find_path(graph_t *g, int src, int dest); 34 | 35 | void find_shortest_path(graph_t *g, int src, int dest); 36 | 37 | #endif // GRAPH_ADJACENCY_LISTS_H 38 | -------------------------------------------------------------------------------- /data-structures/graph/c/linked_list.h: -------------------------------------------------------------------------------- 1 | /* Doubly linked list implementation. */ 2 | #ifndef LINKED_LIST_H 3 | #define LINKED_LIST_H 4 | 5 | #include 6 | #include 7 | 8 | typedef struct linked_list_node 9 | { 10 | int value; 11 | struct linked_list_node *next; 12 | struct linked_list_node *prev; 13 | } linked_list_node_t; 14 | 15 | typedef struct linked_list 16 | { 17 | struct linked_list_node *head; 18 | struct linked_list_node *tail; 19 | } linked_list_t; 20 | 21 | linked_list_t *create_linked_list(void) 22 | { 23 | linked_list_t *list = (linked_list_t *)malloc(sizeof(linked_list_t)); 24 | if (list == NULL) 25 | exit(EXIT_FAILURE); 26 | list->head = NULL; 27 | list->tail = NULL; 28 | return list; 29 | } 30 | 31 | void remove_linked_list(linked_list_t *list) 32 | { 33 | assert(list != NULL); 34 | linked_list_node_t *current = list->head; 35 | linked_list_node_t *next; 36 | while (current != NULL) { 37 | next = current->next; 38 | free(current); 39 | current = next; 40 | } 41 | free(list); 42 | } 43 | 44 | void push_back(linked_list_t *list, int value) 45 | { 46 | linked_list_node_t *node = 47 | (linked_list_node_t *)malloc(sizeof(linked_list_node_t)); 48 | if (node == NULL) 49 | return; 50 | 51 | node->value = value; 52 | node->next = NULL; 53 | node->prev = list->tail; 54 | 55 | if (list->head == NULL) 56 | list->head = node; 57 | else 58 | list->tail->next = node; 59 | 60 | list->tail = node; 61 | } 62 | 63 | void erase(linked_list_t *list, int value) 64 | { 65 | linked_list_node_t *current; 66 | for (current = list->head; current != NULL && current->value != value; 67 | current = current->next); 68 | if (current == NULL) 69 | return; 70 | 71 | if (current->prev == NULL) 72 | list->head = current->next; 73 | else 74 | current->prev->next = current->next; 75 | 76 | if (current->next == NULL) 77 | list->tail = current->prev; 78 | else 79 | current->next->prev = current->prev; 80 | 81 | free(current); 82 | } 83 | 84 | #endif // LINKED_LIST_H 85 | -------------------------------------------------------------------------------- /data-structures/graph/c/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_FIXED_SIZE_ARRAY_H 2 | #define QUEUE_FIXED_SIZE_ARRAY_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct queue 8 | { 9 | int capacity; 10 | int read; 11 | int write; 12 | int *array; 13 | } queue_t; 14 | 15 | queue_t *create_queue(int capacity) 16 | { 17 | queue_t *queue = (queue_t *)malloc(sizeof(queue_t)); 18 | if (queue == NULL) 19 | exit(EXIT_FAILURE); 20 | 21 | queue->capacity = capacity + 1; 22 | queue->read = 0; 23 | queue->write = 0; 24 | queue->array = (int *)malloc(sizeof(int) * queue->capacity); 25 | if (queue->array == NULL) 26 | exit(EXIT_FAILURE); 27 | 28 | return queue; 29 | } 30 | 31 | void remove_queue(queue_t *queue) 32 | { 33 | if (queue == NULL || queue->array == NULL) 34 | return; 35 | free(queue->array); 36 | free(queue); 37 | } 38 | 39 | bool empty_queue(queue_t *queue) 40 | { 41 | return queue->write == queue->read; 42 | } 43 | 44 | void enqueue(queue_t *queue, int value) 45 | { 46 | if ((queue->write + 1) % queue->capacity == queue->read) 47 | return; // The queue is full. 48 | 49 | queue->array[queue->write] = value; 50 | queue->write = (queue->write + 1) % queue->capacity; 51 | } 52 | 53 | int dequeue(queue_t *queue) 54 | { 55 | if (queue->write == queue->read) 56 | return -1; // The queue is empty. 57 | 58 | int res = queue->array[queue->read]; 59 | queue->read = (queue->read + 1) % queue->capacity; 60 | return res; 61 | } 62 | 63 | #endif // QUEUE_FIXED_SIZE_ARRAY_H 64 | -------------------------------------------------------------------------------- /data-structures/graph/c/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_FIXED_SIZE_ARRAY_H 2 | #define STACK_FIXED_SIZE_ARRAY_H 3 | 4 | #include 5 | 6 | typedef struct 7 | { 8 | int top; 9 | int capacity; 10 | int *array; 11 | } stack_t; 12 | 13 | stack_t *create_stack(int capacity) 14 | { 15 | stack_t *st = (stack_t *)malloc(sizeof(stack_t)); 16 | if (st == NULL) 17 | exit(EXIT_FAILURE); 18 | st->capacity = capacity; 19 | st->top = 0; 20 | st->array = (int *)malloc(sizeof(int) * st->capacity); 21 | if (st->array == NULL) 22 | exit(EXIT_FAILURE); 23 | return st; 24 | } 25 | 26 | void remove_stack(stack_t *st) 27 | { 28 | if (st == NULL || st->array == NULL) 29 | return; 30 | free(st->array); 31 | free(st); 32 | } 33 | 34 | void push(stack_t *st, int value) 35 | { 36 | if (st->top == st->capacity) 37 | return; /* Stack is full. */ 38 | st->array[st->top++] = value; 39 | } 40 | 41 | int pop(stack_t *st) 42 | { 43 | if (st->top == 0) 44 | return -1; /* Stack is empty. */ 45 | return st->array[--st->top]; 46 | } 47 | 48 | bool empty_stack(stack_t *st) 49 | { 50 | return st->top == 0; 51 | } 52 | 53 | #endif // STACK_FIXED_SIZE_ARRAY_H -------------------------------------------------------------------------------- /data-structures/graph/c/weighted_graph.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "weighted_graph.h" 6 | 7 | graph_t *create_graph(int vertices) 8 | { 9 | graph_t *graph = (graph_t *)malloc(sizeof(graph_t)); 10 | if (graph == NULL) 11 | exit(EXIT_FAILURE); 12 | graph->edges = 0; 13 | graph->vertices = vertices; 14 | graph->lists = (linked_list_t **)malloc(sizeof(linked_list_t *) * graph->vertices); 15 | if (graph->lists == NULL) 16 | exit(EXIT_FAILURE); 17 | for (unsigned int i = 0; i < graph->vertices; i++) 18 | graph->lists[i] = create_linked_list(); 19 | return graph; 20 | } 21 | 22 | void remove_graph(graph_t *g) 23 | { 24 | assert(g != NULL && g->lists != NULL); 25 | for (unsigned int i = 0; i < g->vertices; i++) 26 | remove_linked_list(g->lists[i]); 27 | free(g); 28 | } 29 | 30 | void add_edge(graph_t *g, unsigned int src, unsigned int dest, 31 | unsigned int weight) 32 | { 33 | if (src >= g->vertices || dest >= g->vertices) 34 | return; 35 | push_back(g->lists[src], dest, weight); 36 | g->edges++; 37 | } 38 | 39 | void remove_edge(graph_t *g, unsigned int src, unsigned int dest) 40 | { 41 | if (src >= g->vertices || dest >= g->vertices) 42 | return; 43 | erase(g->lists[src], dest); 44 | g->edges--; 45 | } 46 | 47 | static inline bool empty_set(bool set[], unsigned int size) 48 | { 49 | for (unsigned int i = 0; i < size; i++) 50 | if (set[i] == true) 51 | return false; 52 | return true; 53 | } 54 | 55 | static inline unsigned int extract_min(bool set[], unsigned int d[], 56 | unsigned int size) 57 | { 58 | unsigned int min = UINT_MAX; 59 | for (unsigned int i = 0; i < size; i++) 60 | if (set[i] == true && d[i] < min) 61 | min = i; 62 | return min; 63 | } 64 | 65 | static void print_shortest_path(int p[], unsigned int src, unsigned int dest) 66 | { 67 | while (dest != src) { 68 | printf("%u ", dest); 69 | dest = p[dest]; 70 | } 71 | printf("%u\n", dest); 72 | } 73 | 74 | /* The shortest path finding using the Dijkstra's algorithm. */ 75 | void find_shortest_path(graph_t *g, unsigned int src, unsigned int dest) 76 | { 77 | #define UNDEFINED -1 78 | if (src >= g->vertices || dest >= g->vertices) 79 | return; 80 | unsigned int d[g->vertices]; int p[g->vertices]; 81 | bool S[g->vertices], Q[g->vertices]; 82 | for (unsigned int i = 0; i < g->vertices; i++) { 83 | p[i] = UNDEFINED; /* Set all parents of vertices to undefined (-1). */ 84 | d[i] = UINT_MAX; /* Mark distances to vertices as infinity (UINT_MAX). */ 85 | S[i] = false; /* Clear the set. */ 86 | Q[i] = true; /* Fill the set with all vertices. */ 87 | } 88 | d[src] = 0; 89 | 90 | while (!empty_set(Q, g->vertices)) { 91 | /* TODO: We should use the fibonacci min-heap here for better performances. */ 92 | unsigned int min = extract_min(Q, d, g->vertices); 93 | Q[min] = false; S[min] = true; 94 | 95 | linked_list_node_t *current = g->lists[min]->head; 96 | for (; current != NULL; current = current->next) { 97 | /* Relaxation condition. */ 98 | if (d[current->value] > d[min] + current->weight) { 99 | d[current->value] = d[min] + current->weight; 100 | p[current->value] = min; 101 | } 102 | } 103 | } 104 | 105 | print_shortest_path(p, src, dest); 106 | printf("weight of path: %u\n", d[dest]); 107 | #undef UNDEFINED 108 | } 109 | -------------------------------------------------------------------------------- /data-structures/graph/c/weighted_graph.h: -------------------------------------------------------------------------------- 1 | #ifndef WEIGHTED_GRAPH_H 2 | #define WEIGHTED_GRAPH_H 3 | 4 | #include "linked_list_weighted.h" 5 | 6 | typedef struct 7 | { 8 | unsigned int vertices; /* number of vertices */ 9 | unsigned int edges; /* number of edges */ 10 | linked_list_t **lists; 11 | } graph_t; 12 | 13 | graph_t *create_graph(int vertices); 14 | 15 | void remove_graph(graph_t *g); 16 | 17 | void add_edge(graph_t *g, unsigned int src, unsigned int dest, 18 | unsigned int weight); 19 | 20 | void remove_edge(graph_t *g, unsigned int src, unsigned int dest); 21 | 22 | static inline bool empty_set(bool set[], unsigned int size); 23 | 24 | static inline unsigned int extract_min(bool set[], unsigned int d[], 25 | unsigned int size); 26 | 27 | static void print_shortest_path(int p[], unsigned int src, unsigned int dest); 28 | 29 | void find_shortest_path(graph_t *g, unsigned int src, unsigned int dest); 30 | 31 | #endif // WEIGHTED_GRAPH_H 32 | -------------------------------------------------------------------------------- /data-structures/graph/maze/README.md: -------------------------------------------------------------------------------- 1 | # The maze solver app 2 | The maze solver application written using the breadth first search (graphs). 3 |
4 | maze 5 |
6 | -------------------------------------------------------------------------------- /data-structures/graph/maze/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfurga/data-structures-and-algorithms/000e1d2789fe57e4325609c6fc100416367d0c74/data-structures/graph/maze/demo.png -------------------------------------------------------------------------------- /data-structures/graph/maze/maze.txt: -------------------------------------------------------------------------------- 1 | ######################################## 2 | #S.##..#.....###.................##....# 3 | ##.#.....#.#...#.######.###..###.#..#### 4 | #..#.###.#.#.###.#....###.##.#.........# 5 | ##...#.###.#.#...#.#.##......########### 6 | ####.....###.#.###.#.#..#..#..#........# 7 | #.....##.#...#.....#.##.#.############.# 8 | #####..###.#########.#..#.#............# 9 | #........#.#.........##.#.##.###.#####.# 10 | #.###.##.#.#.#######..#.#..#.#.#.....#.# 11 | #...#..#.#.#.#........#.####.#.#####.#.# 12 | ###.####.#.#.###.#.#..#......#.......#.# 13 | #...#....#.#.....#######.#####.#####.#.# 14 | ###.#.#.##.#####.#.....#.......#.....#.# 15 | #...###....###.#.#.#.#.###############.# 16 | #.#...########.#.#.#.#.................# 17 | ###.#.#........#.#.#########.########### 18 | #...#....#####.#.#...#.....#.......#...# 19 | #.########...###.#.#.#.#####.#.###.#.### 20 | #..........#.....#.#.........#...#....E# 21 | ######################################## -------------------------------------------------------------------------------- /data-structures/graph/maze/maze_solver.c: -------------------------------------------------------------------------------- 1 | /* 2 | The maze solver app. 3 | The maze based on: https://eduinf.waw.pl/inf/alg/001_search/0128.php. 4 | 5 | Copyright 2019 Mateusz Furga 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef WIN32 13 | #include /* Used for a path highlighting. */ 14 | #endif 15 | 16 | typedef struct 17 | { 18 | unsigned int col; 19 | unsigned int row; 20 | } cord_t; 21 | 22 | typedef struct 23 | { 24 | int capacity; 25 | int read; 26 | int write; 27 | cord_t *array; 28 | } queue_t; 29 | 30 | /* Queue implementation. */ 31 | 32 | queue_t *create_queue(int capacity); 33 | 34 | void remove_queue(queue_t *queue); 35 | 36 | bool empty_queue(queue_t *queue); 37 | 38 | void enqueue(queue_t *queue, cord_t coordinates); 39 | 40 | cord_t dequeue(queue_t *queue); 41 | 42 | bool solve(char **maze, int rows, int cols, cord_t start, cord_t end); 43 | 44 | void print_maze(char **maze, int rows, int cols); 45 | 46 | int main(int argc, char **argv) 47 | { 48 | FILE *f; 49 | char *buffer; 50 | char **maze; 51 | cord_t start, end; 52 | bool verbose = false; 53 | int opt, rows = 0, cols = 0; 54 | 55 | while ((opt = getopt(argc, argv, "r:c:vh")) != -1) { 56 | switch (opt) { 57 | case 'v': 58 | verbose = true; 59 | break; 60 | case 'r': 61 | rows = atoi(optarg); 62 | break; 63 | case 'c': 64 | cols = atoi(optarg); 65 | break; 66 | case 'h': 67 | printf("Usage: %s [-r ROWS] [-c COLUMNS] [-v] [file...]\n", argv[0]); 68 | return 0; 69 | break; 70 | default: 71 | fprintf(stderr, "Usage: %s [-r ROWS] [-c COLUMNS] [-v] [file...]\n", argv[0]); 72 | return 1; 73 | } 74 | } 75 | 76 | if (rows == 0 || cols == 0) { 77 | fprintf(stderr, "ERROR: -r & -c are required.\n"); 78 | return 1; 79 | } 80 | 81 | if ((f = fopen(argv[optind], "r")) == NULL) { 82 | fprintf(stderr, "Unable to open the file %s.\n", argv[optind]); 83 | return 1; 84 | } 85 | 86 | fseek(f, 0, SEEK_END); 87 | size_t sz = ftell(f); 88 | fseek(f, 0, SEEK_SET); 89 | 90 | if ((buffer = (char *)malloc(sizeof(char) * sz)) == NULL) { 91 | fprintf(stderr, "Unable to allocate a memory for the file.\n"); 92 | return 2; 93 | } 94 | fread(buffer, sizeof(char), sz, f); 95 | fclose(f); 96 | 97 | if ((maze = (char **)malloc(sizeof(char *) * rows)) == NULL) { 98 | fprintf(stderr, "Unable to allocate a memory for the maze.\n"); 99 | return 3; 100 | } 101 | 102 | for (int i = 0; i < rows; i++) { 103 | if ((maze[i] = (char *)malloc(sizeof(char) * cols)) == NULL) { 104 | fprintf(stderr, "Unable to allocate a memory for the maze.\n"); 105 | return 4; 106 | } 107 | } 108 | 109 | for (size_t i = 0, j = 0; i < sz; i++) { 110 | switch (buffer[i]) { 111 | case '\n': 112 | continue; 113 | break; 114 | case 'S': 115 | start.col = j % cols; start.row = j / cols; 116 | break; 117 | case 'E': 118 | end.col = j % cols; end.row = j / cols; 119 | buffer[i] = '.'; 120 | break; 121 | } 122 | maze[j / cols][j % cols] = buffer[i]; 123 | j++; 124 | } 125 | free(buffer); 126 | 127 | if (verbose) 128 | print_maze(maze, rows, cols); 129 | 130 | if (solve(maze, rows, cols, start, end) == false) { 131 | fprintf(stderr, "The maze cannot be solved.\n"); 132 | return 5; 133 | } 134 | 135 | print_maze(maze, rows, cols); 136 | return 0; 137 | } 138 | 139 | /* Queue implementation. */ 140 | 141 | queue_t *create_queue(int capacity) 142 | { 143 | queue_t *queue = (queue_t *)malloc(sizeof(queue_t)); 144 | if (queue == NULL) 145 | return NULL; 146 | queue->capacity = capacity + 1; 147 | queue->read = 0; 148 | queue->write = 0; 149 | queue->array = (cord_t *)malloc(sizeof(cord_t) * queue->capacity); 150 | if (queue->array == NULL) 151 | return NULL; 152 | return queue; 153 | } 154 | 155 | void remove_queue(queue_t *queue) 156 | { 157 | if (queue == NULL || queue->array == NULL) 158 | return; 159 | free(queue->array); 160 | free(queue); 161 | } 162 | 163 | bool empty_queue(queue_t *queue) 164 | { 165 | return queue->write == queue->read; 166 | } 167 | 168 | void enqueue(queue_t *queue, cord_t coordinates) 169 | { 170 | if ((queue->write + 1) % queue->capacity == queue->read) 171 | return; // The queue is full. 172 | 173 | queue->array[queue->write] = coordinates; 174 | queue->write = (queue->write + 1) % queue->capacity; 175 | } 176 | 177 | cord_t dequeue(queue_t *queue) 178 | { 179 | cord_t res = queue->array[queue->read]; 180 | queue->read = (queue->read + 1) % queue->capacity; 181 | return res; 182 | } 183 | 184 | bool solve(char **maze, int rows, int cols, cord_t start, cord_t end) 185 | { 186 | queue_t *q = create_queue(rows * cols); 187 | cord_t cur, to_save; 188 | 189 | enqueue(q, start); 190 | while (!empty_queue(q)) { 191 | cur = dequeue(q); 192 | 193 | /* Check if we're done. */ 194 | if (cur.row == end.row && cur.col == end.col) 195 | break; 196 | 197 | /* Up. */ 198 | to_save = cur; 199 | if (maze[cur.row - 1][cur.col + 0] == '.') { 200 | maze[cur.row - 1][cur.col + 0] = 'd'; 201 | to_save.row -= 1; 202 | enqueue(q, to_save); 203 | } 204 | 205 | /* Down. */ 206 | to_save = cur; 207 | if (maze[cur.row + 1][cur.col + 0] == '.') { 208 | maze[cur.row + 1][cur.col + 0] = 'u'; 209 | to_save.row += 1; 210 | enqueue(q, to_save); 211 | } 212 | 213 | /* Right. */ 214 | to_save = cur; 215 | if (maze[cur.row + 0][cur.col - 1] == '.') { 216 | maze[cur.row + 0][cur.col - 1] = 'r'; 217 | to_save.col -= 1; 218 | enqueue(q, to_save); 219 | } 220 | 221 | /* Left. */ 222 | to_save = cur; 223 | if (maze[cur.row + 0][cur.col + 1] == '.') { 224 | maze[cur.row + 0][cur.col + 1] = 'l'; 225 | to_save.col += 1; 226 | enqueue(q, to_save); 227 | } 228 | } 229 | 230 | /* Check if the maze has been solved. */ 231 | if (cur.row != end.row || cur.col != end.col) 232 | return false; 233 | 234 | cur = end; 235 | char c; 236 | while (cur.row != start.row || cur.col != start.col) { 237 | c = maze[cur.row][cur.col]; 238 | maze[cur.row][cur.col] = '+'; 239 | switch (c) { 240 | case 'd': cur.row++; break; 241 | case 'u': cur.row--; break; 242 | case 'r': cur.col++; break; 243 | case 'l': cur.col--; break; 244 | } 245 | } 246 | maze[end.row][end.col] = 'E'; 247 | 248 | /* Clear the maze. */ 249 | for (int i = 0; i < rows; i++) { 250 | for (int j = 0; j < cols; j++) { 251 | switch (maze[i][j]) { 252 | case 'u': case 'd': case 'r': case 'l': case '.': 253 | maze[i][j] = ' '; 254 | } 255 | } 256 | } 257 | 258 | remove_queue(q); 259 | return true; 260 | } 261 | 262 | #ifdef WIN32 263 | void print_path(const char *text, ...) 264 | { 265 | va_list arg; 266 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 267 | 268 | SetConsoleTextAttribute(hConsole, 10); 269 | va_start(arg, text); 270 | vfprintf(stdout, text, arg); 271 | va_end(arg); 272 | SetConsoleTextAttribute(hConsole, 7); 273 | } 274 | #else 275 | void print_path(const char *text, ...) 276 | { 277 | va_list arg; 278 | va_start(arg, text); 279 | vfprintf(stdout, text, arg); 280 | va_end(arg); 281 | } 282 | #endif 283 | 284 | void print_maze(char **maze, int rows, int cols) 285 | { 286 | for (int i = 0; i < rows; i++) { 287 | for (int j = 0; j < cols; j++) { 288 | if (maze[i][j] == '+') 289 | print_path("%c", maze[i][j]); 290 | else 291 | printf("%c", maze[i][j]); 292 | } 293 | printf("\n"); 294 | } 295 | printf("\n"); 296 | } 297 | -------------------------------------------------------------------------------- /data-structures/hash_table/c/hash_table_open_addressing.c: -------------------------------------------------------------------------------- 1 | // Hash table using the open addressing approach (linear probing). 2 | #include 3 | #include 4 | 5 | #include "hash_table_open_addressing.h" 6 | 7 | hash_table_t *create_hash_table(void) 8 | { 9 | hash_table_t *ht = (hash_table_t *)malloc(sizeof(hash_table_t)); 10 | if (ht == NULL) 11 | return NULL; 12 | ht->n = 0; 13 | ht->m = 8; 14 | ht->array = (hash_table_entry_t *)malloc(sizeof(hash_table_entry_t) * ht->m); 15 | if (ht->array == NULL) 16 | return NULL; 17 | 18 | for (int i = 0; i < ht->m; i++) { 19 | ht->array[i].key = NULL; ht->array[i].value = 0; 20 | } 21 | return ht; 22 | } 23 | 24 | static int hash(const char *key, const int m) 25 | { 26 | int hash = 0; 27 | 28 | for (int i = 0; i < strlen(key); i++) { 29 | hash = hash * 29 + key[i]; 30 | } 31 | return abs(hash % m); 32 | } 33 | 34 | void insert(hash_table_t *ht, const char *key, int value) 35 | { 36 | if ((ht->n / (float)ht->m) > 0.6) { 37 | rehash(ht); 38 | } 39 | 40 | int h = hash(key, ht->m); 41 | while (ht->array[h].key != NULL && ht->array[h].key != deleted) { 42 | if (strcmp(ht->array[h].key, key) == 0) { 43 | ht->array[h].value = value; 44 | return; 45 | } 46 | h = (h + 1) % ht->m; 47 | } 48 | 49 | ht->array[h].key = strdup(key); 50 | ht->array[h].value = value; 51 | ht->n++; 52 | } 53 | 54 | int get(hash_table_t *ht, const char *key) 55 | { 56 | int h = hash(key, ht->m); 57 | 58 | if (ht->array[h].key == NULL || ht->array[h].key == deleted) 59 | return -1; 60 | 61 | while (ht->array[h].key != NULL) { 62 | if (strcmp(ht->array[h].key, key) == 0) 63 | return ht->array[h].value; 64 | 65 | h = (h + 1) % ht->m; 66 | } 67 | return -1; 68 | } 69 | 70 | void delete(hash_table_t *ht, const char *key) 71 | { 72 | int h = hash(key, ht->m); 73 | 74 | if (ht->array[h].key == NULL || ht->array[h].key == deleted) 75 | return; 76 | 77 | while (ht->array[h].key != NULL) { 78 | if (strcmp(ht->array[h].key, key) == 0) { 79 | free(ht->array[h].key); 80 | ht->array[h].key = deleted; 81 | ht->n--; 82 | return; 83 | } 84 | h = (h + 1) % ht->m; 85 | } 86 | } 87 | 88 | void rehash(hash_table_t *ht) 89 | { 90 | hash_table_entry_t *array = (hash_table_entry_t *)malloc(sizeof(hash_table_entry_t) * ht->m * 2); 91 | if (array == NULL) 92 | return; 93 | 94 | for (int i = 0; i < ht->m * 2; i++) { 95 | array[i].key = NULL; array[i].value = 0; 96 | } 97 | 98 | int h; 99 | for (int i = 0; i < ht->m; i++) { 100 | if (ht->array[i].key != NULL && ht->array[i].key != deleted) { 101 | h = hash(ht->array[i].key, ht->m * 2); 102 | 103 | while (array[h].key != NULL) { 104 | h = (h + 1) % (ht->m * 2); 105 | } 106 | 107 | array[h].key = ht->array[i].key; 108 | array[h].value = ht->array[i].value; 109 | } 110 | } 111 | 112 | ht->m *= 2; 113 | free(ht->array); 114 | ht->array = array; 115 | } 116 | -------------------------------------------------------------------------------- /data-structures/hash_table/c/hash_table_open_addressing.h: -------------------------------------------------------------------------------- 1 | // Hash table using the open addressing approach (linear probing). 2 | #ifndef HASH_TABLE_OPEN_ADDRESSING_H 3 | #define HASH_TABLE_OPEN_ADDRESSING_H 4 | 5 | static char *deleted = "0"; 6 | 7 | typedef struct { 8 | char *key; 9 | int value; 10 | } hash_table_entry_t; 11 | 12 | typedef struct hash_table { 13 | int n; // number of entries occupied in the hash table 14 | int m; // number of slots in the hash table 15 | hash_table_entry_t *array; 16 | } hash_table_t; 17 | 18 | hash_table_t *create_hash_table(void); 19 | 20 | void insert(hash_table_t *ht, const char *key, int value); 21 | 22 | int get(hash_table_t *ht, const char *key); 23 | 24 | void delete(hash_table_t *ht, const char *key); 25 | 26 | void rehash(hash_table_t *ht); 27 | 28 | static int hash(const char *key, const int m); 29 | 30 | #endif // HASH_TABLE_OPEN_ADDRESSING_H -------------------------------------------------------------------------------- /data-structures/hash_table/cc/hash_table_open_addressing.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "hash_table_open_addressing.h" 3 | 4 | namespace mf 5 | { 6 | 7 | template 8 | HashTable::HashTable() : m_(8), n_(0) 9 | { 10 | array_ = new HashTableEntry*[m_]; 11 | for (int i = 0; i < m_; i++) { 12 | array_[i] = nullptr; 13 | } 14 | dummy_ = new HashTableEntry(); 15 | } 16 | 17 | template 18 | void HashTable::resize_() 19 | { 20 | HashTableEntry **array = new HashTableEntry*[m_ * 2]; 21 | for (int i = 0; i < m_ * 2; i++) { 22 | array[i] = nullptr; 23 | } 24 | m_ *= 2; 25 | 26 | int h; 27 | for (int j = 0; j < m_ / 2; j++) { 28 | if (array_[j] != nullptr && array_[j] != dummy_) { 29 | HashTableEntry *entry = \ 30 | new HashTableEntry(array_[j]->key, array_[j]->value); 31 | h = hash_(array_[j]->key); 32 | 33 | while (array[h] != nullptr) { 34 | h = (h + 1) % m_; 35 | } 36 | array[h] = entry; 37 | } 38 | } 39 | 40 | for (int k = 0; k < m_ / 2; k++) 41 | delete array_[k]; 42 | delete [] array_; 43 | array_ = array; 44 | } 45 | 46 | template 47 | int HashTable::hash_(const K &key) const 48 | { 49 | return std::hash()(key) % m_; 50 | } 51 | 52 | template 53 | void HashTable::insert(const K &key, const V &value) 54 | { 55 | if (n_ / static_cast(m_) > 0.6) { 56 | resize_(); 57 | } 58 | 59 | int h = hash_(key); 60 | 61 | while (array_[h] != nullptr && array_[h] != dummy_) { 62 | if (array_[h]->key == key) { 63 | array_[h]->value = value; 64 | return; 65 | } 66 | h = (h + 1) % m_; 67 | } 68 | 69 | array_[h] = new HashTableEntry(key, value); 70 | n_++; 71 | } 72 | 73 | template 74 | std::optional HashTable::get(const K &key) const 75 | { 76 | int h = hash_(key); 77 | 78 | if (array_[h] == nullptr || array_[h] == dummy_) 79 | return std::nullopt; 80 | 81 | do { 82 | if (array_[h]->key == key) { 83 | return array_[h]->value; 84 | } 85 | h = (h + 1) % m_; 86 | } while (array_[h] != nullptr && array_[h] != dummy_); 87 | 88 | return std::nullopt; 89 | } 90 | 91 | template 92 | void HashTable::remove(const K &key) 93 | { 94 | int h = hash_(key); 95 | 96 | if (array_[h] == nullptr || array_[h] == dummy_) 97 | return; 98 | 99 | do { 100 | if (array_[h]->key == key) { 101 | delete array_[h]; 102 | array_[h] = dummy_; 103 | n_--; 104 | return; 105 | } 106 | h = (h + 1) % m_; 107 | } while (array_[h] != nullptr && array_[h] != dummy_); 108 | } 109 | } // namespace mf 110 | -------------------------------------------------------------------------------- /data-structures/hash_table/cc/hash_table_open_addressing.h: -------------------------------------------------------------------------------- 1 | #ifndef HASH_TABLE_OPEN_ADDRESSING_H 2 | #define HASH_TABLE_OPEN_ADDRESSING_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mf 9 | { 10 | 11 | template 12 | struct HashTableEntry 13 | { 14 | K key; 15 | V value; 16 | 17 | HashTableEntry() {} 18 | HashTableEntry(const K &key, const V &value) : key(key), value(value) {} 19 | }; 20 | 21 | template 22 | class HashTable 23 | { 24 | private: 25 | int m_; 26 | int n_; 27 | HashTableEntry **array_; 28 | HashTableEntry *dummy_; 29 | 30 | void resize_(); 31 | int hash_(const K &key) const; 32 | 33 | public: 34 | HashTable(); 35 | ~HashTable() {}; 36 | 37 | void insert(const K &key, const V &value); 38 | std::optional get(const K &key) const; 39 | void remove(const K &key); 40 | }; 41 | 42 | } // namespace mf 43 | 44 | #endif // HASH_TABLE_OPEN_ADDRESSING_H 45 | -------------------------------------------------------------------------------- /data-structures/hash_table/python/hash_table_open_addressing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # Hash table using the open addressing approach (linear probing). 3 | 4 | from __future__ import division 5 | 6 | 7 | class HashTableEntry(object): 8 | def __init__(self, key=None, value=None): 9 | self.key = key 10 | self.value = value 11 | 12 | 13 | class HashTable(object): 14 | def __init__(self, size=8): 15 | self.array = [HashTableEntry() for _ in xrange(size)] 16 | self.m = size 17 | self.n = 0 18 | 19 | def __setitem__(self, key, value): 20 | return self.insert(key, value) 21 | 22 | def __getitem__(self, key): 23 | return self.get(key) 24 | 25 | def __delitem__(self, key): 26 | return self.delete(key) 27 | 28 | def __str__(self): 29 | return '\n'.join(['%s: %s' % (entry.key, entry.value) for entry in self.array]) 30 | 31 | def _hash(self, key): 32 | return hash(key) % self.m 33 | 34 | def _resize(self): 35 | self.m *= 2 # table doubling 36 | array = [HashTableEntry() for _ in xrange(self.m)] 37 | 38 | for entry in self.array: 39 | if entry.key is not None and entry.key != '': 40 | h = self._hash(entry.key) 41 | while array[h].key is not None: 42 | h = (h + 1) % self.m 43 | 44 | array[h] = entry 45 | 46 | self.array = array 47 | 48 | def insert(self, key, value): 49 | if self.n / self.m > 0.6: # load factor 50 | self._resize() 51 | 52 | h = self._hash(key) 53 | 54 | while self.array[h].key is not None and self.array[h].key != '': 55 | if self.array[h].key == key: 56 | self.array[h].value = value 57 | return 58 | h = (h + 1) % self.m 59 | 60 | self.array[h] = HashTableEntry(key, value) 61 | self.n += 1 62 | 63 | def get(self, key): 64 | h = self._hash(key) 65 | 66 | if self.array[h].key is None: 67 | raise KeyError 68 | 69 | while self.array[h].key is not None: 70 | if self.array[h].key == key: 71 | return self.array[h].value 72 | h = (h + 1) % self.m 73 | else: 74 | raise KeyError 75 | 76 | def delete(self, key): 77 | h = self._hash(key) 78 | 79 | if self.array[h].key is None: 80 | raise KeyError 81 | 82 | while self.array[h].key is not None: 83 | if self.array[h].key == key: 84 | self.array[h].key = '' 85 | n -= 1 86 | return 87 | h = (h + 1) % self.m 88 | else: 89 | raise KeyError 90 | 91 | 92 | if __name__ == '__main__': 93 | hash_table = HashTable(16) 94 | hash_table[0] = 'a' 95 | hash_table[0 + 16] = 'b' 96 | # hash_table[0 + 32] = 'c' 97 | 98 | print hash_table 99 | print hash_table[0 + 32] 100 | -------------------------------------------------------------------------------- /data-structures/heap/c/heap.c: -------------------------------------------------------------------------------- 1 | /* Binary max heap implemented using array. */ 2 | #include 3 | #include 4 | #include 5 | 6 | #include "heap.h" 7 | 8 | #define swap(a, b) int tmp = (a); (a) = (b); (b) = tmp; 9 | 10 | binary_max_heap_t *create_binary_max_heap(void) 11 | { 12 | binary_max_heap_t *h = (binary_max_heap_t *)malloc(sizeof(binary_max_heap_t)); 13 | if (h == NULL) 14 | exit(EXIT_FAILURE); 15 | h->capacity = BINARY_MAX_HEAP_CAPACITY + 1; /* We won't use the first index. */ 16 | h->size = 0; 17 | h->array = (int *)malloc(sizeof(int) * h->capacity); 18 | if (h->array == NULL) 19 | exit(EXIT_FAILURE); 20 | return h; 21 | } 22 | 23 | void delete_binary_max_heap(binary_max_heap_t *h) 24 | { 25 | if (h == NULL || h->array == NULL) 26 | return; 27 | free(h->array); 28 | free(h); 29 | } 30 | 31 | static void sift_up(binary_max_heap_t *h, int index) 32 | { 33 | while (index > 1 && h->array[index] > h->array[index / 2]) { 34 | /* Now we need to swap the values (change their priority). */ 35 | swap(h->array[index], h->array[index / 2]); 36 | index /= 2; 37 | } 38 | } 39 | 40 | static void sift_down(binary_max_heap_t *h, int index) 41 | { 42 | int max_index = index; 43 | /* Check if the left child exists and compare. */ 44 | if (index * 2 <= h->size && 45 | h->array[index * 2] > h->array[max_index]) { 46 | max_index = index * 2; 47 | } 48 | 49 | /* Check if the right child exists and compare. */ 50 | if ((index * 2 + 1) <= h->size && 51 | h->array[index * 2 + 1] > h->array[max_index]) { 52 | max_index = index * 2 + 1; 53 | } 54 | 55 | if (index != max_index) { 56 | swap(h->array[index], h->array[max_index]); 57 | sift_down(h, max_index); 58 | } 59 | } 60 | 61 | void insert(binary_max_heap_t *h, int value) 62 | { 63 | if (h->size == h->capacity) 64 | return; /* Heap is full. */ 65 | 66 | h->array[++h->size] = value; 67 | sift_up(h, h->size); 68 | } 69 | 70 | int extract_max(binary_max_heap_t *h) 71 | { 72 | if (h->size == 0) 73 | return -1; /* Heap is empty. */ 74 | 75 | int res = h->array[1]; 76 | h->array[1] = h->array[h->size--]; 77 | sift_down(h, 1); 78 | return res; 79 | } 80 | 81 | int get_max(binary_max_heap_t *h) 82 | { 83 | if (h->size == 0) 84 | return -1; /* Heap is empty. */ 85 | return h->array[1]; 86 | } 87 | 88 | binary_max_heap_t *heapify(int *array, size_t len) 89 | { 90 | binary_max_heap_t *h = create_binary_max_heap(); 91 | h->size = (int)len; 92 | memcpy(h->array + 1, array, sizeof(int) * len); 93 | 94 | for (int i = h->size / 2; i > 0; i--) { 95 | sift_down(h, i); 96 | } 97 | return h; 98 | } 99 | 100 | void heap_sort(int *array, size_t len) 101 | { 102 | binary_max_heap_t *h = heapify(array, len); 103 | for (int i = 0; i < len; i++) { 104 | array[i] = extract_max(h); 105 | } 106 | delete_binary_max_heap(h); 107 | } 108 | -------------------------------------------------------------------------------- /data-structures/heap/c/heap.h: -------------------------------------------------------------------------------- 1 | /* Binary max heap implemented using array. */ 2 | #ifndef BINARY_MAX_HEAP_H 3 | #define BINARY_MAX_HEAP_H 4 | 5 | #define BINARY_MAX_HEAP_CAPACITY 256 6 | 7 | typedef struct 8 | { 9 | int capacity; 10 | int size; 11 | int *array; 12 | } binary_max_heap_t; 13 | 14 | binary_max_heap_t *create_binary_max_heap(void); 15 | 16 | void delete_binary_max_heap(binary_max_heap_t *h); 17 | 18 | static void sift_up(binary_max_heap_t *h, int index); 19 | 20 | static void sift_down(binary_max_heap_t *h, int index); 21 | 22 | void insert(binary_max_heap_t *h, int value); 23 | 24 | int extract_max(binary_max_heap_t *h); 25 | 26 | int get_max(binary_max_heap_t *h); 27 | 28 | binary_max_heap_t *heapify(int *array, size_t len); 29 | 30 | void heap_sort(int *array, size_t len); 31 | 32 | #endif // BINARY_MAX_HEAP_H 33 | -------------------------------------------------------------------------------- /data-structures/heap/python/heap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | class Heap(object): 4 | def __init__(self): 5 | self.t = [] 6 | 7 | @property 8 | def n(self): 9 | return len(self.t) 10 | 11 | @classmethod 12 | def build(cls, t): 13 | self = cls() 14 | self.t = t 15 | for i in range(Heap.parent(self.n - 1), -1, -1): 16 | self._heapify(i) 17 | return self 18 | 19 | @staticmethod 20 | def left(i): 21 | return 2 * i + 1 22 | 23 | @staticmethod 24 | def right(i): 25 | return 2 * i + 2 26 | 27 | @staticmethod 28 | def parent(i): 29 | return (i - 1) // 2 30 | 31 | def _heapify(self, i): 32 | l = Heap.left(i) 33 | r = Heap.right(i) 34 | m = i 35 | 36 | if l < self.n and self.t[l] > self.t[m]: 37 | m = l 38 | if r < self.n and self.t[r] > self.t[m]: 39 | m = r 40 | 41 | if m != i: 42 | self.t[m], self.t[i] = self.t[i], self.t[m] 43 | self._heapify(m) 44 | 45 | def get_max(self): 46 | return self.t[0] 47 | 48 | def extract_max(self): 49 | if self.n <= 0: 50 | return None 51 | self.t[0], self.t[self.n - 1] = self.t[self.n - 1], self.t[0] 52 | max = self.t.pop() 53 | self._heapify(0) 54 | return max 55 | 56 | def increase_key(self, i, key): 57 | if key < self.t[i]: 58 | return 59 | self.t[i] = key 60 | while i > 0 and self.t[Heap.parent(i)] < self.t[i]: 61 | self.t[Heap.parent(i)], self.t[i] = self.t[i], self.t[Heap.parent(i)] 62 | i = Heap.parent(i) 63 | 64 | def insert(self, elem): 65 | self.t.append(float("-inf")) 66 | self.increase_key(self.n - 1, elem) 67 | 68 | -------------------------------------------------------------------------------- /data-structures/linked_list/c/linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "linked_list.h" 5 | 6 | linked_list_t *create_linked_list(void) 7 | { 8 | linked_list_t *list = (linked_list_t *)malloc(sizeof(linked_list_t)); 9 | if (list == NULL) { 10 | fprintf(stderr, "Unable to allocate the memory for the linked_list_t.\n"); 11 | exit(EXIT_FAILURE); 12 | } 13 | list->head = NULL; 14 | list->tail = NULL; 15 | return list; 16 | } 17 | 18 | int size(linked_list_t *list) 19 | { 20 | int count = 0; 21 | for (linked_list_node_t *i = list->head; i != NULL; i = i->next) { 22 | count++; 23 | } 24 | return count; 25 | } 26 | 27 | bool is_empty(linked_list_t *list) 28 | { 29 | return list->head == NULL; 30 | } 31 | 32 | void push_front(linked_list_t *list, int value) 33 | { 34 | linked_list_node_t *node = (linked_list_node_t *)malloc(sizeof(linked_list_node_t)); 35 | if (node == NULL) { 36 | fprintf(stderr, "Unable to allocate the memory for the linked_list_node_t.\n"); 37 | return; 38 | } 39 | node->value = value; 40 | node->prev = NULL; 41 | node->next = list->head; 42 | 43 | if (list->head == NULL) 44 | list->tail = node; 45 | else 46 | list->head->prev = node; 47 | 48 | list->head = node; 49 | } 50 | 51 | int pop_front(linked_list_t *list) 52 | { 53 | if (list->head == NULL) { 54 | fprintf(stderr, "The linked list is empty.\n"); 55 | return -1; 56 | } 57 | linked_list_node_t *node = list->head; 58 | int value = node->value; 59 | 60 | list->head = list->head->next; 61 | if (list->head == NULL) 62 | list->tail = NULL; 63 | else 64 | list->head->prev = NULL; 65 | 66 | free(node); 67 | return value; 68 | } 69 | 70 | void push_back(linked_list_t *list, int value) 71 | { 72 | linked_list_node_t *node = (linked_list_node_t *)malloc(sizeof(linked_list_node_t)); 73 | if (node == NULL) { 74 | fprintf(stderr, "Unable to allocate the memory for the linked_list_node_t.\n"); 75 | return; 76 | } 77 | node->value = value; 78 | node->next = NULL; 79 | node->prev = list->tail; 80 | 81 | if (list->head == NULL) 82 | list->head = node; 83 | else 84 | list->tail->next = node; 85 | 86 | list->tail = node; 87 | } 88 | 89 | int pop_back(linked_list_t *list) 90 | { 91 | if (list->head == NULL) { 92 | fprintf(stderr, "The linked list is empty.\n"); 93 | return -1; 94 | } 95 | linked_list_node_t *node = list->tail; 96 | int value = node->value; 97 | 98 | list->tail = list->tail->prev; 99 | if (list->tail == NULL) 100 | list->head = NULL; 101 | else 102 | list->tail->next = NULL; 103 | 104 | free(node); 105 | return value; 106 | } 107 | 108 | int front(linked_list_t *list) 109 | { 110 | if (list->head == NULL) { 111 | fprintf(stderr, "The linked list is empty.\n"); 112 | return -1; 113 | } 114 | return list->head->value; 115 | } 116 | 117 | int back(linked_list_t *list) 118 | { 119 | if (list->head == NULL) { 120 | fprintf(stderr, "The linked list is empty.\n"); 121 | return -1; 122 | } 123 | return list->tail->value; 124 | } 125 | 126 | void insert(linked_list_t *list, int index, int value) 127 | { 128 | if (index < 0 || index >= size(list)) { 129 | fprintf(stderr, "Invalid index.\n"); 130 | return; 131 | } 132 | 133 | linked_list_node_t *node = (linked_list_node_t *)malloc(sizeof(linked_list_node_t)); 134 | if (node == NULL) { 135 | fprintf(stderr, "Unable to allocate the memory for the linked_list_node_t.\n"); 136 | return; 137 | } 138 | node->value = value; 139 | 140 | linked_list_node_t *in = list->head; 141 | for (int i = 0; i != index; i++, in = in->next); 142 | 143 | node->next = in; 144 | node->prev = in->prev; 145 | 146 | if (in->prev == NULL) 147 | list->head = node; 148 | else 149 | in->prev->next = node; 150 | 151 | in->prev = node; 152 | } 153 | 154 | void erase(linked_list_t *list, int index) 155 | { 156 | if (index < 0 || index >= size(list)) { 157 | fprintf(stderr, "Invalid index.\n"); 158 | return; 159 | } 160 | 161 | linked_list_node_t *in = list->head; 162 | for (int i = 0; i != index; i++, in = in->next); 163 | 164 | if (in->prev == NULL) 165 | list->head = in->next; 166 | else 167 | in->prev->next = in->next; 168 | 169 | if (in->next == NULL) 170 | list->tail = in->prev; 171 | else 172 | in->next->prev = in->prev; 173 | 174 | free(in); 175 | } 176 | 177 | void reverse(linked_list_t *list) 178 | { 179 | if (list->head == NULL || list->head->next == NULL) 180 | return; 181 | 182 | list->tail = list->head; 183 | linked_list_node_t *tmp = NULL; 184 | 185 | for (linked_list_node_t *in = list->head; in != NULL; in = in->prev) { 186 | tmp = in->prev; 187 | in->prev = in->next; 188 | in->next = tmp; 189 | } 190 | 191 | list->head = tmp->prev; 192 | } 193 | -------------------------------------------------------------------------------- /data-structures/linked_list/c/linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef LINKED_LIST_H 2 | #define LINKED_LIST_H 3 | 4 | #include 5 | 6 | typedef struct linked_list_node 7 | { 8 | int value; 9 | struct linked_list_node *prev; 10 | struct linked_list_node *next; 11 | } linked_list_node_t; 12 | 13 | typedef struct linked_list 14 | { 15 | struct linked_list_node *head; 16 | struct linked_list_node *tail; 17 | } linked_list_t; 18 | 19 | linked_list_t *create_linked_list(void); 20 | 21 | int size(linked_list_t *list); 22 | 23 | bool is_empty(linked_list_t *list); 24 | 25 | void push_front(linked_list_t *list, int value); 26 | 27 | int pop_front(linked_list_t *list); 28 | 29 | void push_back(linked_list_t *list, int value); 30 | 31 | int pop_back(linked_list_t *list); 32 | 33 | int front(linked_list_t *list); 34 | 35 | int back(linked_list_t *list); 36 | 37 | void insert(linked_list_t *list, int index, int value); 38 | 39 | void erase(linked_list_t *list, int index); 40 | 41 | void reverse(linked_list_t *list); 42 | 43 | #endif // LINKED_LIST_H 44 | -------------------------------------------------------------------------------- /data-structures/linked_list/cc/linked_list.cc: -------------------------------------------------------------------------------- 1 | #include "linked_list.h" 2 | 3 | namespace mf 4 | { 5 | 6 | template 7 | LinkedList::~LinkedList() 8 | { 9 | LinkedListNode *current = head_; 10 | LinkedListNode *next = nullptr; 11 | 12 | while (current) { 13 | next = current->get_next(); 14 | delete current; 15 | current = next; 16 | } 17 | } 18 | 19 | template 20 | int LinkedList::size() const 21 | { 22 | int count = 0; 23 | for (LinkedListNode *i = head_; i != nullptr; i = i->get_next()) { 24 | count++; 25 | } 26 | return count; 27 | } 28 | 29 | template 30 | bool LinkedList::is_empty() const 31 | { 32 | return head_ == nullptr; 33 | } 34 | 35 | template 36 | std::optional LinkedList::value_at(int index) const 37 | { 38 | if (index < 0 || index >= this->size()) 39 | return std::nullopt; 40 | 41 | LinkedListNode *node = head_; 42 | for (int i = 0; i != index; i++, node = node->get_next()); 43 | 44 | return node->get_value(); 45 | } 46 | 47 | template 48 | void LinkedList::push_front(T value) 49 | { 50 | LinkedListNode *node = new LinkedListNode(value); 51 | node->set_prev(nullptr); 52 | node->set_next(head_); 53 | 54 | if (head_ == nullptr) 55 | tail_ = node; 56 | else 57 | head_->set_prev(node); 58 | 59 | head_ = node; 60 | } 61 | 62 | template 63 | std::optional LinkedList::pop_front() 64 | { 65 | if (head_ == nullptr) 66 | return std::nullopt; 67 | 68 | LinkedListNode *node = head_; 69 | T value = node->get_value(); 70 | 71 | head_ = head_->get_next(); 72 | if (head_ == nullptr) 73 | tail_ = nullptr; 74 | else 75 | head_->set_prev(nullptr); 76 | 77 | delete node; 78 | return value; 79 | } 80 | 81 | template 82 | void LinkedList::push_back(T value) 83 | { 84 | LinkedListNode *node = new LinkedListNode(value); 85 | node->set_prev(tail_); 86 | node->set_next(nullptr); 87 | 88 | if (head_ == nullptr) 89 | head_ = node; 90 | else 91 | tail_->set_next(node); 92 | 93 | tail_ = node; 94 | } 95 | 96 | template 97 | std::optional LinkedList::pop_back() 98 | { 99 | if (head_ == nullptr) 100 | return std::nullopt; 101 | 102 | LinkedListNode *node = tail_; 103 | T value = node->get_value(); 104 | 105 | tail_ = tail_->get_prev(); 106 | if (tail_ == nullptr) 107 | head_ = nullptr; 108 | else 109 | tail_->set_next(nullptr); 110 | 111 | delete node; 112 | return value; 113 | } 114 | 115 | template 116 | std::optional LinkedList::front() const 117 | { 118 | if (head_ == nullptr) 119 | return std::nullopt; 120 | return head_->get_value(); 121 | } 122 | 123 | template 124 | std::optional LinkedList::back() const 125 | { 126 | if (head_ == nullptr) 127 | return std::nullopt; 128 | return tail_->get_value(); 129 | } 130 | 131 | template 132 | void LinkedList::insert(int index, T value) 133 | { 134 | if (index < 0 || index >= this->size()) 135 | return; 136 | 137 | LinkedListNode *node = new LinkedListNode(value); 138 | LinkedListNode *in = head_; 139 | for (int i = 0; i != index; i++, in = in->get_next()); 140 | 141 | node->set_next(in); 142 | node->set_prev(in->get_prev()); 143 | 144 | if (in->get_prev() == nullptr) 145 | head_ = node; 146 | else 147 | in->get_prev()->set_next(node); 148 | 149 | in->set_prev(node); 150 | } 151 | 152 | template 153 | void LinkedList::erase(int index) 154 | { 155 | if (index < 0 || index >= this->size()) 156 | return; 157 | 158 | LinkedListNode *in = head_; 159 | for (int i = 0; i != index; i++, in = in->get_next()); 160 | 161 | if (in->get_prev() == nullptr) 162 | head_ = in->get_next(); 163 | else 164 | in->get_prev()->set_next(in->get_next()); 165 | 166 | if (in->get_next() == nullptr) 167 | tail_ = in->get_prev(); 168 | else 169 | in->get_next()->set_prev(in->get_prev()); 170 | 171 | delete in; 172 | } 173 | 174 | template 175 | void LinkedList::reverse() 176 | { 177 | if (head_ == nullptr || head_->get_next() == nullptr) 178 | return; 179 | 180 | tail_ = head_; 181 | LinkedListNode *tmp = nullptr; 182 | 183 | for (LinkedListNode *i = head_; i != nullptr; i = i->get_prev()) { 184 | tmp = i->get_prev(); 185 | i->set_prev(i->get_next()); 186 | i->set_next(tmp); 187 | } 188 | 189 | head_ = tmp->get_prev(); 190 | } 191 | 192 | } // namespace mf 193 | -------------------------------------------------------------------------------- /data-structures/linked_list/cc/linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef LINKED_LIST_H 2 | #define LINKED_LIST_H 3 | 4 | #include 5 | 6 | namespace mf 7 | { 8 | 9 | template 10 | class LinkedListNode 11 | { 12 | private: 13 | T value_; 14 | LinkedListNode *prev_; 15 | LinkedListNode *next_; 16 | 17 | public: 18 | LinkedListNode(const T &value) : value_(value), prev_(nullptr), next_(nullptr) {} 19 | ~LinkedListNode() {} 20 | 21 | const T &get_value() const { return value_; } 22 | LinkedListNode *get_next() const { return next_; } 23 | LinkedListNode *get_prev() const { return prev_; } 24 | 25 | void set_value(const T &value) { value_ = value; } 26 | void set_next(LinkedListNode *next) { next_ = next; } 27 | void set_prev(LinkedListNode *prev) { prev_ = prev; } 28 | }; 29 | 30 | template 31 | class LinkedList 32 | { 33 | private: 34 | LinkedListNode *head_; 35 | LinkedListNode *tail_; 36 | 37 | public: 38 | LinkedList() : head_(nullptr), tail_(nullptr) {} 39 | ~LinkedList(); 40 | LinkedList(const LinkedList &) = delete; 41 | LinkedList &operator=(const LinkedList &) = delete; 42 | 43 | int size() const; 44 | bool is_empty() const; 45 | 46 | std::optional value_at(int index) const; 47 | 48 | void push_front(T value); 49 | std::optional pop_front(); 50 | 51 | void push_back(T value); 52 | std::optional pop_back(); 53 | 54 | std::optional front() const; 55 | std::optional back() const; 56 | 57 | void insert(int index, T value); 58 | void erase(int index); 59 | 60 | void reverse(); 61 | }; 62 | 63 | } // namespace mf 64 | 65 | #endif // LINKED_LIST_H 66 | -------------------------------------------------------------------------------- /data-structures/linked_list/python/linked_list.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/evn python2 2 | 3 | 4 | class LinkedListNode(object): 5 | def __init__(self, value): 6 | self._value = value 7 | self._prev = None 8 | self._next = None 9 | 10 | @property 11 | def value(self): 12 | return self._value 13 | 14 | @value.setter 15 | def value(self, value): 16 | self._value = value 17 | 18 | @property 19 | def next(self): 20 | return self._next 21 | 22 | @next.setter 23 | def next(self, next): 24 | self._next = next 25 | 26 | @property 27 | def prev(self): 28 | return self._prev 29 | 30 | @prev.setter 31 | def prev(self, prev): 32 | self._prev = prev 33 | 34 | 35 | class LinkedList(object): 36 | def __init__(self): 37 | self._head = None # Instance of LinkedListNode 38 | self._tail = None # Instance of LinkedListNode 39 | 40 | def __len__(self): 41 | size = 0 42 | node = self._head 43 | while node is not None: 44 | size += 1 45 | node = node.next 46 | return size 47 | 48 | def is_empty(self): 49 | return self._head is None 50 | 51 | def push_front(self, value): 52 | node = LinkedListNode(value) 53 | node.prev = None 54 | node.next = self._head 55 | 56 | if self._head is None: 57 | self._tail = None 58 | else: 59 | self._head.prev = node 60 | 61 | self._head = node 62 | 63 | def pop_front(self): 64 | if self._head is None: 65 | return 66 | 67 | node = self._head 68 | value = node.value 69 | 70 | self._head = self._head.next 71 | if self._head is None: 72 | self._tail = None 73 | else: 74 | self._head.prev = None 75 | 76 | del node 77 | return value 78 | 79 | def push_back(self, value): 80 | node = LinkedListNode(value) 81 | node.prev = self._tail 82 | node.next = None 83 | 84 | if self._head is None: 85 | self._head = node 86 | else: 87 | self._tail.next = node 88 | 89 | self._tail = node 90 | 91 | def pop_back(self): 92 | if self._head is None: 93 | return 94 | 95 | node = self._tail 96 | value = node.value 97 | 98 | self._tail = self._tail.prev 99 | if self._tail is None: 100 | self._head = None 101 | else: 102 | self._tail.next = None 103 | 104 | del node 105 | return value 106 | 107 | def front(self): 108 | if self._head is None: 109 | return 110 | return self._head.value 111 | 112 | def back(self): 113 | if self._head is None: 114 | return 115 | return self._tail.value 116 | 117 | def insert(self, index, value): 118 | if index < 0 or index >= len(self): 119 | return 120 | 121 | node = LinkedListNode(value) 122 | it = self._head 123 | i = 0 124 | while i != index: 125 | it = it.next 126 | i += 1 127 | 128 | node.next = it 129 | node.prev = it.prev 130 | 131 | if it.prev is None: 132 | self._head = node 133 | else: 134 | it.prev.next = node 135 | 136 | it.prev = node 137 | 138 | def erase(self, index): 139 | if index < 0 or index >= len(self): 140 | return 141 | 142 | it = self._head 143 | i = 0 144 | while i != index: 145 | it = it.next 146 | i += 1 147 | 148 | if it.prev is None: 149 | self._head = it.next 150 | else: 151 | it.prev.next = it.next 152 | 153 | if it.next is None: 154 | self._tail = it.prev 155 | else: 156 | it.next.prev = it.prev 157 | 158 | del it 159 | 160 | def reverse(self): 161 | if self._head is None or self._head.next is None: 162 | return 163 | 164 | self._tail = self._head 165 | tmp = None 166 | i = self._head 167 | 168 | while i is not None: 169 | tmp = i.prev 170 | i.prev, i.next = i.next, i.prev 171 | i = i.prev 172 | 173 | self._head = tmp.prev 174 | -------------------------------------------------------------------------------- /data-structures/queue/c/queue_array.c: -------------------------------------------------------------------------------- 1 | // Queue using the fixed-sized array. 2 | 3 | #include 4 | #include "queue_array.h" 5 | 6 | queue_t *create_queue(int capacity) 7 | { 8 | queue_t *queue = (queue_t *)malloc(sizeof(queue_t)); 9 | if (queue == NULL) 10 | exit(EXIT_FAILURE); 11 | 12 | queue->capacity = capacity + 1; 13 | queue->read = 0; 14 | queue->write = 0; 15 | queue->array = (int *)malloc(sizeof(int) * queue->capacity); 16 | if (queue->array == NULL) 17 | exit(EXIT_FAILURE); 18 | 19 | return queue; 20 | } 21 | 22 | void enqueue(queue_t *queue, int value) 23 | { 24 | if ((queue->write + 1) % queue->capacity == queue->read) 25 | return; // The queue is full. 26 | 27 | queue->array[queue->write] = value; 28 | queue->write = (queue->write + 1) % queue->capacity; 29 | } 30 | 31 | int dequeue(queue_t *queue) 32 | { 33 | if (queue->write == queue->read) 34 | return -1; // The queue is empty. 35 | 36 | int res = queue->array[queue->read]; 37 | queue->read = (queue->read + 1) % queue->capacity; 38 | return res; 39 | } 40 | -------------------------------------------------------------------------------- /data-structures/queue/c/queue_array.h: -------------------------------------------------------------------------------- 1 | // Queue using the fixed-sized array. 2 | 3 | #ifndef QUEUE_FIXED_SIZE_ARRAY_H 4 | #define QUEUE_FIXED_SIZE_ARRAY_H 5 | 6 | #include 7 | 8 | typedef struct queue 9 | { 10 | int capacity; 11 | int read; 12 | int write; 13 | int *array; 14 | } queue_t; 15 | 16 | queue_t *create_queue(int capacity); 17 | 18 | void enqueue(queue_t *queue, int value); 19 | 20 | int dequeue(queue_t *queue); 21 | 22 | bool empty(queue_t *queue); 23 | 24 | #endif // QUEUE_FIXED_SIZE_ARRAY_H 25 | -------------------------------------------------------------------------------- /data-structures/queue/c/queue_linked_list.c: -------------------------------------------------------------------------------- 1 | // Queue using the linked list data structure. 2 | 3 | #include 4 | #include "queue_linked_list.h" 5 | 6 | queue_t *create_queue(void) 7 | { 8 | queue_t *queue = (queue_t *)malloc(sizeof(queue_t)); 9 | if (queue == NULL) 10 | exit(EXIT_FAILURE); 11 | 12 | queue->head = NULL; 13 | queue->tail = NULL; 14 | return queue; 15 | } 16 | 17 | void enqueue(queue_t *queue, int value) 18 | { 19 | queue_node_t *node = (queue_node_t *)malloc(sizeof(queue_node_t)); 20 | if (node == NULL) 21 | return; 22 | node->value = value; 23 | node->next = NULL; 24 | 25 | if (queue->head == NULL) 26 | queue->head = node; 27 | else 28 | queue->tail->next = node; 29 | 30 | queue->tail = node; 31 | } 32 | 33 | int dequeue(queue_t *queue) 34 | { 35 | if (queue->head == NULL) 36 | return -1; // The queue is empty. 37 | 38 | queue_node_t *node = queue->head; 39 | int value = node->value; 40 | 41 | queue->head = queue->head->next; 42 | if (queue->head == NULL) 43 | queue->tail = NULL; 44 | 45 | free(node); 46 | return value; 47 | } 48 | 49 | bool empty(queue_t *queue) 50 | { 51 | return queue->head == NULL; 52 | } 53 | -------------------------------------------------------------------------------- /data-structures/queue/c/queue_linked_list.h: -------------------------------------------------------------------------------- 1 | // Queue using the linked list data structure. 2 | 3 | #ifndef QUEUE_LINKED_LIST_H 4 | #define QUEUE_LINKED_LIST_H 5 | 6 | #include 7 | 8 | typedef struct queue_node 9 | { 10 | int value; 11 | struct queue_node *next; 12 | } queue_node_t; 13 | 14 | typedef struct queue 15 | { 16 | struct queue_node *head; 17 | struct queue_node *tail; 18 | } queue_t; 19 | 20 | queue_t *create_queue(void); 21 | 22 | void enqueue(queue_t *queue, int value); 23 | 24 | int dequeue(queue_t *queue); 25 | 26 | bool empty(queue_t *queue); 27 | 28 | #endif // QUEUE_LINKED_LIST_H 29 | -------------------------------------------------------------------------------- /data-structures/queue/cc/queue_array.cc: -------------------------------------------------------------------------------- 1 | #include "queue_array.h" 2 | 3 | namespace mf 4 | { 5 | 6 | template 7 | void Queue::enqueue(T value) 8 | { 9 | if ((write_ + 1) % capacity_ == read_) 10 | return; 11 | 12 | array_[write_] = value; 13 | write_ = (write_ + 1) % capacity_; 14 | } 15 | 16 | template 17 | std::optional Queue::dequeue() 18 | { 19 | if (write_ == read_) 20 | return std::nullopt; 21 | 22 | T res = array_[read_]; 23 | read_ = (read_ + 1) % capacity_; 24 | return res; 25 | } 26 | 27 | } // namespace mf 28 | -------------------------------------------------------------------------------- /data-structures/queue/cc/queue_array.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_ARRAY_H 2 | #define QUEUE_ARRAY_H 3 | 4 | #include 5 | #include 6 | 7 | namespace mf 8 | { 9 | 10 | template 11 | class Queue 12 | { 13 | private: 14 | int read_; 15 | int write_; 16 | int capacity_; 17 | std::unique_ptr array_; 18 | 19 | public: 20 | Queue(int capacity) : read_(0), write_(0), capacity_(capacity + 1) { 21 | array_ = std::unique_ptr(new T[capacity_]); 22 | } 23 | ~Queue() {}; 24 | 25 | void enqueue(T value); 26 | std::optional dequeue(); 27 | }; 28 | 29 | } // namespace mf 30 | 31 | #endif // QUEUE_ARRAY_H 32 | -------------------------------------------------------------------------------- /data-structures/queue/cc/queue_linked_list.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "queue_linked_list.h" 3 | 4 | namespace mf 5 | { 6 | 7 | template 8 | Queue::~Queue() 9 | { 10 | QueueNode *current = head_; 11 | QueueNode *next = nullptr; 12 | 13 | while (current != nullptr) { 14 | next = current->get_next(); 15 | delete current; 16 | current = next; 17 | } 18 | } 19 | 20 | template 21 | void Queue::enqueue(T value) 22 | { 23 | QueueNode *node = new QueueNode(value); 24 | node->set_next(nullptr); 25 | 26 | if (head_ == nullptr) 27 | head_ = node; 28 | else 29 | tail_->set_next(node); 30 | 31 | tail_ = node; 32 | } 33 | 34 | template 35 | std::optional Queue::dequeue() 36 | { 37 | if (head_ == nullptr) 38 | return std::nullopt; 39 | 40 | QueueNode *node = head_; 41 | T value = node->get_value(); 42 | 43 | head_ = head_->get_next(); 44 | if (head_ == nullptr) 45 | tail_ = nullptr; 46 | 47 | delete node; 48 | return value; 49 | } 50 | 51 | } // namespace mf 52 | -------------------------------------------------------------------------------- /data-structures/queue/cc/queue_linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_LINKED_LIST_H 2 | #define QUEUE_LINKED_LIST_H 3 | 4 | #include 5 | 6 | namespace mf 7 | { 8 | template 9 | class QueueNode 10 | { 11 | private: 12 | T value_; 13 | QueueNode *next_; 14 | 15 | public: 16 | QueueNode(const T &value) : value_(value), next_(nullptr) {} 17 | ~QueueNode() {} 18 | 19 | const T &get_value() const { return value_; } 20 | QueueNode *get_next() const { return next_; } 21 | 22 | void set_value(const T &value) { value_ = value; } 23 | void set_next(QueueNode *next) { next_ = next; } 24 | }; 25 | 26 | template 27 | class Queue 28 | { 29 | private: 30 | QueueNode *head_; 31 | QueueNode *tail_; 32 | 33 | public: 34 | Queue() : head_(nullptr), tail_(nullptr) {} 35 | ~Queue(); 36 | 37 | void enqueue(T value); 38 | std::optional dequeue(); 39 | }; 40 | 41 | } // namespace mf 42 | 43 | #endif // QUEUE_LINKED_LIST_H 44 | -------------------------------------------------------------------------------- /data-structures/queue/python/queue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | 4 | class QueueNode(object): 5 | def __init__(self, value): 6 | self._value = value 7 | self._next = None 8 | 9 | @property 10 | def value(self): 11 | return self._value 12 | 13 | @value.setter 14 | def value(self, value): 15 | self._value = value 16 | 17 | @property 18 | def next(self): 19 | return self._next 20 | 21 | @next.setter 22 | def next(self, next): 23 | self._next = next 24 | 25 | 26 | class Queue(object): 27 | def __init__(self): 28 | self._head = None 29 | self._tail = None 30 | 31 | def enqueue(self, value): 32 | node = QueueNode(value) 33 | node.next = None 34 | 35 | if self._head is None: 36 | self._head = node 37 | else: 38 | self._tail.next = node 39 | 40 | self._tail = node 41 | 42 | def dequeue(self): 43 | if self._head is None: 44 | return 45 | 46 | node = self._head 47 | value = node.value 48 | 49 | self._head = self._head.next 50 | if self._head is None: 51 | self._tail = None 52 | 53 | del node 54 | return value 55 | 56 | def empty(self): 57 | return self._head is None 58 | -------------------------------------------------------------------------------- /data-structures/stack/c/reverse_polish_notation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "reverse_polish_notation.h" 3 | 4 | int parse_reverse_polish_notation(const char expression[]) 5 | { 6 | /* This parser doesn't check if the given expression is correct! */ 7 | stack_t *s = create_stack(); 8 | int a, b, res; 9 | 10 | for (unsigned int i = 0; expression[i] != '='; i++) { 11 | if (expression[i] >= '0' && expression[i] <= '9') { 12 | push(s, expression[i] - '0'); continue; 13 | } 14 | switch (expression[i]) { 15 | case '+': 16 | b = pop(s); a = pop(s); 17 | push(s, a + b); 18 | break; 19 | case '-': 20 | b = pop(s); a = pop(s); 21 | push(s, a - b); 22 | break; 23 | case '*': 24 | b = pop(s); a = pop(s); 25 | push(s, a * b); 26 | break; 27 | case '/': 28 | b = pop(s); a = pop(s); 29 | push(s, a / b); 30 | break; 31 | } 32 | } 33 | res = pop(s); 34 | remove_stack(s); 35 | return res; 36 | } 37 | 38 | void convert_to_reverse_polish_notation(const char expression[]) 39 | { 40 | stack_t *s = create_stack(); 41 | for (unsigned int i = 0; expression[i] != '='; i++) { 42 | if (expression[i] >= '0' && expression[i] <= '9') { 43 | printf("%c", expression[i]); continue; 44 | } 45 | switch (expression[i]) { 46 | case '(': 47 | push(s, expression[i]); 48 | break; 49 | case ')': 50 | while (!empty_stack(s) && top(s) != '(') 51 | printf("%c", pop(s)); 52 | pop(s); /* Remove the opening bracket. */ 53 | break; 54 | case '+': 55 | case '-': 56 | case '*': 57 | case '/': 58 | while (!empty_stack(s) && (top(s) == '*' || top(s) == '/')) 59 | printf("%c", pop(s)); 60 | push(s, expression[i]); 61 | break; 62 | } 63 | } 64 | printf("%c", pop(s)); 65 | remove_stack(s); 66 | } 67 | 68 | int main(void) 69 | { 70 | // char expression[] = "352*+="; 71 | // printf("%i\n", parse_reverse_polish_notation(expression)); 72 | 73 | char expression[] = "(5+3)*2/(2*5-3)="; 74 | convert_to_reverse_polish_notation(expression); 75 | 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /data-structures/stack/c/reverse_polish_notation.h: -------------------------------------------------------------------------------- 1 | #ifndef REVERSE_POLISH_NOTATION_H 2 | #define REVERSE_POLISH_NOTATION_H 3 | 4 | #include 5 | #include 6 | 7 | int parse_reverse_polish_notation(const char expression[]); 8 | 9 | void convert_to_reverse_polish_notation(const char expression[]); 10 | 11 | /* A dynamic stack implementation below. */ 12 | 13 | typedef struct stack_node 14 | { 15 | int value; 16 | struct stack_node *next; 17 | } stack_node_t; 18 | 19 | typedef struct 20 | { 21 | stack_node_t *head; 22 | } stack_t; 23 | 24 | stack_t *create_stack(void) 25 | { 26 | stack_t *s = (stack_t *)malloc(sizeof(stack_t)); 27 | if (s == NULL) 28 | exit(EXIT_FAILURE); 29 | s->head = NULL; 30 | return s; 31 | } 32 | 33 | void remove_stack(stack_t *s) 34 | { 35 | if (s == NULL) 36 | return; 37 | stack_node_t *curr = s->head; 38 | stack_node_t *next = NULL; 39 | for (; curr != NULL; curr = next) { 40 | next = curr->next; 41 | free(curr); 42 | } 43 | free(s); 44 | } 45 | 46 | void push(stack_t *s, int value) 47 | { 48 | stack_node_t *node = (stack_node_t *)malloc(sizeof(stack_node_t)); 49 | if (node == NULL) 50 | return; 51 | node->value = value; 52 | node->next = s->head; 53 | s->head = node; 54 | } 55 | 56 | int pop(stack_t *s) 57 | { 58 | if (s->head == NULL) 59 | return -1; /* The stack is empty. */ 60 | stack_node_t *node = s->head; 61 | int v = node->value; 62 | s->head = s->head->next; 63 | free(node); 64 | return v; 65 | } 66 | 67 | int top(stack_t *s) 68 | { 69 | return s->head->value; 70 | } 71 | 72 | bool empty_stack(stack_t *s) 73 | { 74 | return s->head == NULL; 75 | } 76 | 77 | /* End of a dynamic stack implementation. */ 78 | 79 | #endif // REVERSE_POLISH_NOTATION_H 80 | -------------------------------------------------------------------------------- /data-structures/stack/cc/reverse_polish_notation.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "reverse_polish_notation.h" 4 | 5 | namespace mf 6 | { 7 | 8 | int parse_reverse_polish_notation(const char expression[]) 9 | { 10 | /* This parser doesn't check if the given expression is correct! */ 11 | std::stack s; 12 | int a, b; 13 | 14 | for (unsigned int i = 0; expression[i] != '='; i++) { 15 | if (expression[i] >= '0' && expression[i] <= '9') 16 | s.push(expression[i] - '0'); 17 | else { 18 | switch (expression[i]) { 19 | case '+': 20 | b = s.top(); s.pop(); 21 | a = s.top(); s.pop(); 22 | s.push(a + b); 23 | break; 24 | case '-': 25 | b = s.top(); s.pop(); 26 | a = s.top(); s.pop(); 27 | s.push(a - b); 28 | break; 29 | case '*': 30 | b = s.top(); s.pop(); 31 | a = s.top(); s.pop(); 32 | s.push(a * b); 33 | break; 34 | case '/': 35 | b = s.top(); s.pop(); 36 | a = s.top(); s.pop(); 37 | s.push(a / b); 38 | break; 39 | } 40 | } 41 | } 42 | return s.top(); 43 | } 44 | 45 | void convert_to_reverse_polish_notation(const char expression[]) 46 | { 47 | std::stack s; 48 | 49 | for (unsigned int i = 0; expression[i] != '='; i++) { 50 | if (expression[i] >= '0' && expression[i] <= '9') 51 | std::cout << expression[i]; 52 | else { 53 | switch (expression[i]) { 54 | case '(': 55 | s.push(expression[i]); 56 | break; 57 | case ')': 58 | while (!s.empty() && s.top() != '(') { 59 | std::cout << s.top(); s.pop(); 60 | } 61 | s.pop(); /* Remove the opening bracket. */ 62 | break; 63 | case '+': 64 | case '-': 65 | case '*': 66 | case '/': 67 | while (!s.empty() && (s.top() == '*' || s.top() == '/')) { 68 | std::cout << s.top(); s.pop(); 69 | } 70 | s.push(expression[i]); 71 | break; 72 | } 73 | } 74 | } 75 | std::cout << s.top() << std::endl; 76 | } 77 | 78 | } // namespace mf 79 | 80 | int main() 81 | { 82 | // std::cout << mf::parse_reverse_polish_notation("352*+=") << std::endl; 83 | mf::convert_to_reverse_polish_notation("(5+3)*2/(2*5-3)="); 84 | return 0; 85 | } -------------------------------------------------------------------------------- /data-structures/stack/cc/reverse_polish_notation.h: -------------------------------------------------------------------------------- 1 | #ifndef REVERSE_POLISH_NOTATION_H 2 | #define REVERSE_POLISH_NOTATION_H 3 | 4 | namespace mf 5 | { 6 | 7 | int parse_reverse_polish_notation(const char expression[]); 8 | 9 | void convert_to_reverse_polish_notation(const char expression[]); 10 | 11 | } // namespace mf 12 | 13 | #endif // REVERSE_POLISH_NOTATION_H 14 | -------------------------------------------------------------------------------- /data-structures/stack/python/reverse_polish_notation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from typing import List, Dict, Callable 5 | 6 | # types 7 | Stack = List 8 | 9 | def _add(s: Stack, a: int, b: int): 10 | s.append(a + b) 11 | 12 | def _sub(s: Stack, a: int, b: int): 13 | s.append(a - b) 14 | 15 | def _mul(s: Stack, a: int, b: int): 16 | s.append(a * b) 17 | 18 | def _div(s: Stack, a: int, b: int): 19 | s.append(a / b) 20 | 21 | def parse_reverse_polish_notation(expression: str) -> int: 22 | """Parses the reverse polish notation given in `expression` and 23 | evaluates it. 24 | NOTE: This parser doesn't check if the `expression` is correct! 25 | """ 26 | OPERATIONS: Dict[str, Callable[Stack, int, int]] = { 27 | '+': _add, 28 | '-': _sub, 29 | '*': _mul, 30 | '/': _div 31 | } 32 | s: Stack[int] = [] 33 | 34 | # Go through 0..n-1, where n is the last element. 35 | # We assumes that the last element is '='. 36 | for c in expression[:-1]: 37 | if '0' <= c <= '9': 38 | s.append(int(c)) 39 | continue 40 | 41 | try: 42 | b = s.pop() 43 | a = s.pop() 44 | OPERATIONS[c](s, a, b) 45 | except KeyError: 46 | continue 47 | 48 | return s.pop() 49 | 50 | def convert_to_reverse_polish_notation(expression: str) -> None: 51 | """Converts the given `expression` into the reverse polish notation.""" 52 | s: Stack[str] = [] 53 | 54 | # Go through 0..n-1, where n is the last element. 55 | # We assumes that the last element is '='. 56 | for c in expression[:-1]: 57 | if '0' <= c <= '9': 58 | print(c, end='') 59 | continue 60 | 61 | if c == '(': 62 | s.append(c) 63 | elif c == ')': 64 | while len(s) > 0 and s[-1] != '(': 65 | print('%c' % s.pop(), end='') 66 | s.pop() # Remove the opening bracket 67 | elif c in ('+', '-', '*', '/'): 68 | while len(s) > 0 and (s[-1] == '*' or s[-1] == '/'): 69 | print('%c' % s.pop(), end='') 70 | s.append(c) 71 | 72 | print('%c' % s.pop(), end='') 73 | 74 | 75 | if __name__ == '__main__': 76 | # print(parse_reverse_polish_notation('53+2*25*3-/=')) 77 | convert_to_reverse_polish_notation('(5+3)*2/(2*5-3)=') 78 | --------------------------------------------------------------------------------