├── .gitignore ├── 2022-2023 └── 10b │ ├── 2022-09-21-revision-2 │ ├── functions.h │ ├── functions.c │ └── main.c │ ├── 2022-12-07-bst-3 │ ├── quicksort.h │ ├── vector.h │ ├── vector.c │ ├── bst.h │ ├── main.c │ └── quicksort.c │ ├── 2022-12-19-bst-4 │ ├── quicksort.h │ ├── vector.h │ ├── vector.c │ ├── main.c │ ├── bst.h │ └── quicksort.c │ ├── 2023-02-06-graph-3 │ ├── vector.h │ └── vector.c │ ├── 2023-02-10-graph-4 │ ├── vector.h │ └── vector.c │ ├── 2023-02-17-dijkstra │ ├── vector.h │ └── vector.c │ ├── 2022-12-13-exam2-solution │ ├── ver2 │ │ ├── linked_list.h │ │ ├── priority_queue.h │ │ ├── main.c │ │ └── linked_list.c │ └── ver1 │ │ ├── priority_queue.h │ │ └── main.c │ ├── 2023-03-06-a-star │ ├── vector.h │ ├── queue.h │ ├── vector.c │ └── queue.c │ ├── 2023-02-24-dijkstra-route │ ├── vector.h │ ├── queue.h │ ├── vector.c │ └── queue.c │ ├── 2022-09-26-revision-3 │ ├── list.h │ ├── main.c │ └── list.c │ ├── 2022-10-05-quicksort-exercise │ └── main.c │ ├── 2023-06-02-encryption-1 │ └── main.c │ ├── 2023-06-09-des-1 │ └── main.c │ ├── 2022-09-19-revision │ └── main.c │ ├── 2023-01-11-graph-1 │ └── main.c │ ├── 2023-04-03-compression-2 │ └── main.c │ ├── 2023-04-24-lzw-1 │ └── main.c │ ├── 2022-10-17-conuntingsort │ └── main.c │ ├── 2023-06-05-encryption-2 │ └── main.c │ ├── 2022-10-10-quicksort-2 │ └── main.c │ ├── 2022-10-12-bucketsort-exercise │ └── main.c │ └── 2022-11-30-bst │ └── main.c ├── README.md ├── 2024-2025 ├── 10a │ ├── 2024-09-19-C_revision │ │ ├── foo.h │ │ └── foo.c │ ├── utils │ │ ├── tree.h │ │ ├── stack.h │ │ ├── queue.h │ │ ├── graph_h.h │ │ ├── hashmap.h │ │ ├── pqueue.h │ │ ├── graph.h │ │ ├── stack.c │ │ ├── tree.c │ │ ├── graph.c │ │ ├── graph_h.c │ │ └── queue.c │ ├── 2024-11-07-trees │ │ ├── tree.h │ │ ├── main.c │ │ └── tree.c │ ├── 2024-11-25-avl │ │ ├── tree.h │ │ └── main.c │ ├── 2024-12-09-tree_exercises │ │ └── tree.h │ ├── 2024-10-07-linked_list │ │ ├── main.c │ │ └── list.h │ ├── 2025-01-10-rb-tree │ │ ├── main.c │ │ └── tree.h │ ├── 2024-10-14-stack │ │ ├── stack.h │ │ ├── stack.c │ │ └── main.c │ ├── 2024-09-26-vector │ │ └── main.c │ ├── 2024-12-2-heap │ │ └── main.c │ ├── 2025-02-12-graphs │ │ ├── graphMatrix.c │ │ └── graph.c │ ├── 2025-05-15-graph-hashmap-and-leet-tasks │ │ └── evaluateDivision.c │ ├── 2025-07-09-consultation │ │ └── dsu.c │ └── 2024-10-23-mergeSort │ │ └── main.c ├── 10v │ ├── 2024_10_18 SkipList │ │ ├── Makefile │ │ ├── skiplist.h │ │ ├── main.c │ │ └── skiplist.c │ ├── 2024_10_11 DoublyLinkedLists │ │ ├── Makefile │ │ ├── main.c │ │ └── dLinkedList.h │ ├── 2024_11_13 set and treeSet │ │ ├── Set │ │ │ ├── set.h │ │ │ └── set.c │ │ ├── TreeSet │ │ │ └── treeSet.h │ │ └── main.c │ ├── 2024_12_11 heap │ │ ├── vector.h │ │ ├── vector.c │ │ └── main.c │ ├── 2024_11_27 avl │ │ ├── avlTree.h │ │ └── main.c │ ├── 2025_02_25 graph traversal │ │ ├── queue.h │ │ └── queue.c │ ├── 2025_04_15 hashmap │ │ └── ransomNode.c │ ├── 2025_04_23 huffman │ │ ├── pqueue.h │ │ └── pqueue.c │ ├── Kontrolno 1 example │ │ └── dLinkedList.h │ ├── 2024_11_22 bfs │ │ └── dLinkedList_TreeNode.h │ ├── 2024_09_20 C revision │ │ └── main.c │ └── 2025_02_18 graphs │ │ └── adjMatrixGraph.c └── 10b │ ├── 2025-05-27-des-1 │ ├── helpers.h │ └── index.c │ ├── 2024-10-02-linked-list │ └── example.c │ ├── 2024-09-25-intro-1 │ └── main.c │ ├── 2024-10-07-quick-sort │ └── main.c │ ├── 2024-10-28-set │ └── main.c │ └── 2024-11-18-bst-1 │ └── main.c ├── 2023-2024 ├── 10a │ ├── 2023-09-20-C_revision │ │ ├── foo.c │ │ └── foo.h │ ├── 2023-10-10-Exercise_2 │ │ ├── loop_list.png │ │ └── dlist.h │ ├── 2023-09-29-Exercise_1 │ │ ├── selection_sort.gif │ │ ├── merge-two-sorted-arrays.png │ │ └── vector.h │ ├── utils │ │ ├── dsu.h │ │ ├── graph_matrix.h │ │ ├── vector.h │ │ ├── graph.h │ │ ├── graph_h.h │ │ ├── pqueue.h │ │ ├── hash.h │ │ ├── dsu.c │ │ ├── dlist.h │ │ ├── graph_matrix.c │ │ ├── graph.c │ │ └── graph_h.c │ ├── 2023-10-04-Insertion_sort_and_lists │ │ ├── list.h │ │ ├── list_preview.c │ │ ├── dlist_preview.c │ │ └── dlist.h │ ├── 2023-10-25-skip-list │ │ ├── main.c │ │ └── skip_list.h │ ├── 2023-11-29-tree4 │ │ ├── queue.h │ │ └── queue.c │ ├── 2023-10-13-Excersise │ │ └── main.c │ ├── 2024-03-26-leet-code-graphs │ │ └── keys_and_rooms.c │ ├── 2024-06-05-lzw │ │ └── lzw.c │ ├── 2024-04-17-dsu_leet_code │ │ └── path_exists.c │ ├── 2024-04-09-hash-map-tasks │ │ └── main.c │ ├── 2023-12-06-heap │ │ └── main.c │ ├── 2024-02-14-graphs │ │ └── graph_matrix.c │ └── 2024-03-05-graphs3 │ │ └── main.c └── 10b │ ├── 2024-04-15-hashmap │ ├── main.c │ ├── list.h │ ├── map.h │ ├── list.c │ └── map.c │ ├── 2023-10-02-intro-3 │ ├── list.h │ └── list.c │ ├── 2023-10-06-intro-4 │ ├── list.h │ └── list.c │ ├── 2023-09-25-intro-2 │ ├── vector.h │ ├── main.c │ └── vector.c │ ├── 2024-02-19-graph-1 │ ├── list.h │ ├── graph.h │ ├── list.c │ └── main.c │ ├── 2024-02-26-graph-2 │ ├── list.h │ ├── graph.h │ └── list.c │ ├── 2023-09-18-intro │ └── main.c │ ├── 2023-11-20-bst-2 │ ├── queue.h │ └── queue.c │ ├── 2023-11-27-bst-3 │ ├── queue.h │ └── queue.c │ ├── 2023-12-11-bst-4 │ ├── queue.h │ └── queue.c │ ├── 2024-03-11-graph-3 │ ├── list.h │ ├── graph_utilities.h │ ├── graph.h │ ├── list.c │ └── main.c │ ├── 2024-03-18-dijkstra-2 │ ├── list.h │ ├── graph_utilities.h │ ├── graph.h │ ├── priority_queue.h │ ├── list.c │ └── main.c │ ├── 2024-04-29-huffman-coding │ ├── list.h │ ├── map.h │ ├── main.c │ ├── list.c │ └── map.c │ ├── 2024-05-10-huffman-coding-2 │ ├── list.h │ ├── map.h │ ├── list.c │ └── map.c │ ├── 2023-11-03-recursion-recap │ └── main.c │ ├── 2023-10-09-insertion-sort │ └── main.c │ ├── 2023-10-23-skip-list │ └── main.c │ ├── 2024-01-04-exam-2-solution │ └── main.c │ ├── 2024-01-26-exam-3 │ └── main.c │ └── 2023-11-11-heap-sort │ └── main.c └── 2025-2026 ├── 10a ├── 2025-09-24-c_revision │ ├── foo.c │ └── foo.h ├── utils │ ├── bst.h │ ├── vector.h │ ├── stack.h │ ├── queue.h │ ├── bst.c │ ├── stack.c │ ├── queue.c │ └── vector.c ├── 2025-09-29-vector │ ├── vector.h │ ├── main.c │ └── vector.c ├── 2025-10-15-stack │ ├── stack.h │ ├── main.c │ ├── insertionSort.c │ ├── merge.c │ └── stack.c ├── 2025-10-06-list │ ├── list.h │ └── main.c ├── 2025-10-22-binary-search │ └── main.c └── 2025-10-27-mergesort │ └── main.c └── 10b ├── 2025-09-29-bubblesort └── main.c ├── 2025-10-06-mergesort └── main.c └── 2025-09-25-intro └── main.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.o 3 | .vscode -------------------------------------------------------------------------------- /2022-2023/10b/2022-09-21-revision-2/functions.h: -------------------------------------------------------------------------------- 1 | int foo(); 2 | 3 | void bar(); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uasd 2 | Official repo for the Introduction to Algorithms and Data structures course 3 | -------------------------------------------------------------------------------- /2024-2025/10a/2024-09-19-C_revision/foo.h: -------------------------------------------------------------------------------- 1 | #ifndef H_FOO 2 | #define H_FOO 3 | 4 | int bar(); 5 | 6 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-07-bst-3/quicksort.h: -------------------------------------------------------------------------------- 1 | void swap(int *a, int *b); 2 | void quick_sort(int *arr, unsigned int size); 3 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-19-bst-4/quicksort.h: -------------------------------------------------------------------------------- 1 | void swap(int *a, int *b); 2 | void quick_sort(int *arr, unsigned int size); 3 | -------------------------------------------------------------------------------- /2024-2025/10a/2024-09-19-C_revision/foo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "foo.h" 3 | 4 | int bar() { 5 | printf("bar"); 6 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-09-20-C_revision/foo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "foo.h" 3 | 4 | int foo() 5 | { 6 | printf("foo\n"); 7 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-15-hashmap/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf("Hello\n"); 5 | return 0; 6 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-10-Exercise_2/loop_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elsys/uasd/HEAD/2023-2024/10a/2023-10-10-Exercise_2/loop_list.png -------------------------------------------------------------------------------- /2022-2023/10b/2022-09-21-revision-2/functions.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo() { 4 | return 5; 5 | } 6 | 7 | void bar() { 8 | printf("bar"); 9 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-09-29-Exercise_1/selection_sort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elsys/uasd/HEAD/2023-2024/10a/2023-09-29-Exercise_1/selection_sort.gif -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-07-bst-3/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | int* values; 3 | int count; 4 | }; 5 | 6 | void add_to_vector(struct vector_t* vec, int value); 7 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-19-bst-4/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | int* values; 3 | int count; 4 | }; 5 | 6 | void add_to_vector(struct vector_t* vec, int value); 7 | -------------------------------------------------------------------------------- /2023-2024/10a/2023-09-20-C_revision/foo.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef FOO 3 | #define FOO 4 | // guard за да се предпазим от това да дефинираме два пъти 5 | 6 | int foo(); 7 | 8 | #endif -------------------------------------------------------------------------------- /2023-2024/10a/2023-09-29-Exercise_1/merge-two-sorted-arrays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elsys/uasd/HEAD/2023-2024/10a/2023-09-29-Exercise_1/merge-two-sorted-arrays.png -------------------------------------------------------------------------------- /2025-2026/10a/2025-09-24-c_revision/foo.c: -------------------------------------------------------------------------------- 1 | #include "foo.h" 2 | #include 3 | float dist2 (Point2* p1, Point2* p2) { 4 | return sqrt((p1->x - p2->x)*(p1->x - p2->x) + (p1->y - p2->y)*(p1->y - p2->y)); 5 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-06-graph-3/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | void** values; 3 | int size; 4 | }; 5 | 6 | void vector_add(struct vector_t* vec, void* value); 7 | void* vector_get(struct vector_t* vec, int index); 8 | -------------------------------------------------------------------------------- /2025-2026/10a/2025-09-24-c_revision/foo.h: -------------------------------------------------------------------------------- 1 | #ifndef _POINT_H_ 2 | #define _POINT_H_ 3 | 4 | typedef struct Point2 { 5 | float x; 6 | float y; 7 | } Point2; 8 | 9 | float dist2(Point2* a, Point2* b); 10 | 11 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-10-graph-4/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | void** values; 3 | int size; 4 | }; 5 | 6 | void vector_add(struct vector_t* vec, void* value); 7 | void* vector_get(struct vector_t* vec, int index); 8 | struct vector_t* vector_init(); 9 | -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-17-dijkstra/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | void** values; 3 | int size; 4 | }; 5 | 6 | void vector_add(struct vector_t* vec, void* value); 7 | void* vector_get(struct vector_t* vec, int index); 8 | struct vector_t* vector_init(); 9 | -------------------------------------------------------------------------------- /2024-2025/10v/2024_10_18 SkipList/Makefile: -------------------------------------------------------------------------------- 1 | all: main.out 2 | 3 | skiplist.o: skiplist.h skiplist.c 4 | gcc -c skiplist.c -o skiplist.o 5 | 6 | main.out: skiplist.o main.c 7 | gcc main.c skiplist.o -o main.out 8 | 9 | clean: 10 | rm -f *.o *.out -------------------------------------------------------------------------------- /2023-2024/10a/utils/dsu.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef DSU_H 3 | #define DSU_H 4 | 5 | typedef struct Subset 6 | { 7 | int parent; 8 | int rank; 9 | } Subset; 10 | 11 | int Find(Subset *subsets, int i); 12 | void Union(Subset *subsets, int src, int dest); 13 | 14 | #endif -------------------------------------------------------------------------------- /2024-2025/10v/2024_10_11 DoublyLinkedLists/Makefile: -------------------------------------------------------------------------------- 1 | all: main.out 2 | 3 | dLinkedList.o: dLinkedList.h dLinkedList.c 4 | gcc -c dLinkedList.c -o dLinkedList.o 5 | 6 | main.out: dLinkedList.o main.c 7 | gcc main.c dLinkedList.o -o main.out 8 | 9 | clean: 10 | rm -f *.o *.out -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-13-exam2-solution/ver2/linked_list.h: -------------------------------------------------------------------------------- 1 | struct list_node_t { 2 | struct list_node_t* next; 3 | struct list_node_t* tail; 4 | int value; 5 | }; 6 | 7 | struct list_node_t* push_list(struct list_node_t* head, int value); 8 | 9 | int pop_list(struct list_node_t** head); -------------------------------------------------------------------------------- /2023-2024/10b/2023-10-02-intro-3/list.h: -------------------------------------------------------------------------------- 1 | struct list_t { 2 | struct list_t* next; 3 | int value; 4 | }; 5 | 6 | typedef struct list_t list_t; 7 | 8 | list_t* init_list(); 9 | void push_list(list_t* vec, int value); 10 | int list_get_at(list_t* vec, unsigned int index); -------------------------------------------------------------------------------- /2023-2024/10b/2023-10-06-intro-4/list.h: -------------------------------------------------------------------------------- 1 | struct list_t { 2 | struct list_t* next; 3 | int value; 4 | }; 5 | 6 | typedef struct list_t list_t; 7 | 8 | list_t* init_list(); 9 | void push_list(list_t* vec, int value); 10 | int list_get_at(list_t* vec, unsigned int index); -------------------------------------------------------------------------------- /2024-2025/10a/utils/tree.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_H 2 | #define TREE_H 3 | 4 | struct Node { 5 | int val; 6 | struct Node* left; 7 | struct Node* right; 8 | } typedef Node; 9 | 10 | Node* create_node(int); 11 | Node* bst_insert(Node*, int); 12 | void printTree(Node*); 13 | 14 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2023-03-06-a-star/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | void** values; 3 | int size; 4 | }; 5 | 6 | void vector_add(struct vector_t* vec, void* value); 7 | void* vector_get(struct vector_t* vec, int index); 8 | struct vector_t* vector_init(); 9 | void vector_reverse(struct vector_t* vec); 10 | -------------------------------------------------------------------------------- /2023-2024/10b/2023-09-25-intro-2/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | int* arr; 3 | unsigned int count; 4 | }; 5 | 6 | typedef struct vector_t vector_t; 7 | 8 | vector_t* init_vector(); 9 | void push_vector(vector_t* vec, int value); 10 | int vector_get_at(vector_t* vec, unsigned int index); -------------------------------------------------------------------------------- /2024-2025/10a/2024-11-07-trees/tree.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_H 2 | #define TREE_H 3 | 4 | struct Node { 5 | int val; 6 | struct Node* left; 7 | struct Node* right; 8 | } typedef Node; 9 | 10 | Node* create_node(int); 11 | Node* bst_insert(Node*, int); 12 | void printTree(Node*); 13 | 14 | #endif -------------------------------------------------------------------------------- /2025-2026/10a/utils/bst.h: -------------------------------------------------------------------------------- 1 | #ifndef BST_H 2 | #define BST_H 3 | 4 | typedef struct Node { 5 | int val; 6 | struct Node* left; 7 | struct Node* right; 8 | } Node; 9 | 10 | Node* init_node(int val); 11 | void inorder(Node* root); 12 | Node* bst_insert(Node* root, int val); 13 | 14 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-24-dijkstra-route/vector.h: -------------------------------------------------------------------------------- 1 | struct vector_t { 2 | void** values; 3 | int size; 4 | }; 5 | 6 | void vector_add(struct vector_t* vec, void* value); 7 | void* vector_get(struct vector_t* vec, int index); 8 | struct vector_t* vector_init(); 9 | void vector_reverse(struct vector_t* vec); 10 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-09-26-revision-3/list.h: -------------------------------------------------------------------------------- 1 | struct list_node_t { 2 | int value; 3 | struct list_node_t *next; 4 | }; 5 | 6 | void print_list(struct list_node_t *head); 7 | struct list_node_t * push_front(struct list_node_t *head, int new_value); 8 | struct list_node_t * push_back(struct list_node_t *head, int new_value); -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-07-bst-3/vector.c: -------------------------------------------------------------------------------- 1 | #include "vector.h" 2 | #include 3 | 4 | void add_to_vector(struct vector_t* vec, int value) { 5 | vec->values = realloc( 6 | vec->values, 7 | sizeof(int) * (vec->count + 1) 8 | ); 9 | vec->values[vec->count] = value; 10 | vec->count++; 11 | } 12 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-19-bst-4/vector.c: -------------------------------------------------------------------------------- 1 | #include "vector.h" 2 | #include 3 | 4 | void add_to_vector(struct vector_t* vec, int value) { 5 | vec->values = realloc( 6 | vec->values, 7 | sizeof(int) * (vec->count + 1) 8 | ); 9 | vec->values[vec->count] = value; 10 | vec->count++; 11 | } 12 | -------------------------------------------------------------------------------- /2023-2024/10b/2024-02-19-graph-1/list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct list_t { 4 | struct list_t* next; 5 | void* value; 6 | }; 7 | 8 | typedef struct list_t list_t; 9 | 10 | list_t* init_list(); 11 | void push_list(list_t* vec, void* value); 12 | void* list_get_at(list_t* vec, unsigned int index); -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-07-bst-3/bst.h: -------------------------------------------------------------------------------- 1 | struct node_t { 2 | int value; 3 | struct node_t *left; 4 | struct node_t *right; 5 | }; 6 | 7 | struct node_t * create_node(int value); 8 | void add(struct node_t *root, int value); 9 | void print_dfs(struct node_t* root, int level); 10 | struct node_t* balance_tree(struct node_t* root); 11 | -------------------------------------------------------------------------------- /2024-2025/10v/2024_11_13 set and treeSet/Set/set.h: -------------------------------------------------------------------------------- 1 | #ifndef SET_T 2 | #define SET_T 3 | 4 | typedef struct Set { 5 | int size; 6 | int capacity; 7 | int* data; 8 | } Set; 9 | 10 | Set* initSet(); 11 | 12 | int setContains(Set* set, int val); 13 | 14 | void setAdd(Set* set, int val); 15 | 16 | void printSet(Set* set); 17 | 18 | #endif -------------------------------------------------------------------------------- /2023-2024/10b/2024-02-26-graph-2/list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct list_t { 4 | struct list_t* next; 5 | void* value; 6 | }; 7 | 8 | typedef struct list_t list_t; 9 | 10 | list_t* init_list(); 11 | void push_list(list_t* list, void* value); 12 | void* list_get_at(list_t* list, unsigned int index); 13 | int list_length(list_t* list); -------------------------------------------------------------------------------- /2024-2025/10a/2024-11-07-trees/main.c: -------------------------------------------------------------------------------- 1 | #include "tree.h" 2 | 3 | int main() { 4 | Node* root = create_node(10); 5 | bst_insert(root, 5); 6 | bst_insert(root, 15); 7 | bst_insert(root, 30); 8 | bst_insert(root, 0); 9 | bst_insert(root, 4); 10 | bst_insert(root, 26); 11 | 12 | 13 | printTree(root); 14 | 15 | return 0; 16 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-13-exam2-solution/ver2/priority_queue.h: -------------------------------------------------------------------------------- 1 | struct priority_queue_t { 2 | struct list_node_t** subqueues; 3 | int size; 4 | }; 5 | 6 | struct priority_queue_t* init_queue(); 7 | 8 | void push_queue(struct priority_queue_t* q, int value, int priority); 9 | 10 | int pop_queue(struct priority_queue_t* q); 11 | 12 | void print_queue(struct priority_queue_t* q); -------------------------------------------------------------------------------- /2024-2025/10a/2024-11-25-avl/tree.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_H 2 | #define TREE_H 3 | 4 | struct Node { 5 | int val; 6 | struct Node* left; 7 | struct Node* right; 8 | int height; 9 | } typedef Node; 10 | 11 | Node* create_node(int); 12 | Node* bst_insert(Node*, int); 13 | void printTree(Node*); 14 | Node* left_rotation(Node *x); 15 | Node* right_rotation(Node *y); 16 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-07-bst-3/main.c: -------------------------------------------------------------------------------- 1 | #include "bst.h" 2 | 3 | int main() { 4 | struct node_t* root = create_node(10); 5 | add(root, 6); 6 | add(root, 16); 7 | add(root, 5); 8 | add(root, 2); 9 | add(root, 4); 10 | add(root, 12); 11 | 12 | print_dfs(root, 0); 13 | 14 | root = balance_tree(root); 15 | print_dfs(root, 0); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-19-bst-4/main.c: -------------------------------------------------------------------------------- 1 | #include "bst.h" 2 | 3 | int main() { 4 | struct node_t* root = create_node(10); 5 | add(root, 6); 6 | add(root, 16); 7 | add(root, 5); 8 | add(root, 2); 9 | add(root, 4); 10 | add(root, 12); 11 | 12 | print_dfs(root, 0); 13 | 14 | root = balance_tree(root); 15 | print_dfs(root, 0); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-19-bst-4/bst.h: -------------------------------------------------------------------------------- 1 | struct node_t { 2 | int value; 3 | struct node_t *left; 4 | struct node_t *right; 5 | }; 6 | 7 | struct node_t * create_node(int value); 8 | void add(struct node_t *root, int value); 9 | void print_dfs(struct node_t* root, int level); 10 | struct node_t* balance_tree(struct node_t* root); 11 | 12 | int find(struct node_t *root, int value); 13 | -------------------------------------------------------------------------------- /2023-2024/10a/utils/graph_matrix.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPH_MATRIX_H 2 | #define GRAPH_MATRIX_H 3 | 4 | typedef struct Graph 5 | { 6 | int numVertices; 7 | int **adjMatrix; 8 | } Graph; 9 | 10 | Graph *init_graph(int numVertices); 11 | void addEdgeDirectional(Graph *graph, int from, int to); 12 | void addEdge(Graph *graph, int from, int to); 13 | void printGraph(Graph *graph); 14 | 15 | #endif -------------------------------------------------------------------------------- /2024-2025/10a/2024-12-09-tree_exercises/tree.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_H 2 | #define TREE_H 3 | 4 | struct Node { 5 | int val; 6 | struct Node* left; 7 | struct Node* right; 8 | int height; 9 | } typedef Node; 10 | 11 | Node* create_node(int); 12 | Node* bst_insert(Node*, int); 13 | void printTree(Node*); 14 | Node* left_rotation(Node *x); 15 | Node* right_rotation(Node *y); 16 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2023-03-06-a-star/queue.h: -------------------------------------------------------------------------------- 1 | struct queue_node_t { 2 | struct queue_node_t* next; 3 | void* value; 4 | int priority; 5 | }; 6 | 7 | struct queue_t { 8 | struct queue_node_t* head; 9 | struct queue_node_t* tail; 10 | }; 11 | 12 | struct queue_t* init_queue(); 13 | void queue_add(struct queue_t* q, void* value); 14 | void* queue_remove(struct queue_t* q); -------------------------------------------------------------------------------- /2023-2024/10b/2023-09-18-intro/main.c: -------------------------------------------------------------------------------- 1 | int* sort(int arr[], int count) { 2 | //int res[count]; 3 | int *res = malloc(count * sizeof(int)); 4 | 5 | // ??? 6 | 7 | 8 | (*res) = 10; 9 | *(res + 0) = 10; 10 | res[0] = 10; 11 | 12 | *(res + 1) = 20; 13 | res[1] = 20; 14 | 15 | return res; 16 | } 17 | 18 | int main() { 19 | return 0; 20 | } -------------------------------------------------------------------------------- /2023-2024/10b/2023-09-25-intro-2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vector.h" 4 | 5 | int main() { 6 | vector_t* vec = init_vector(); 7 | 8 | for(int i = 0; i < 10; i++) { 9 | push_vector(vec, i); 10 | } 11 | 12 | for(int i = 0; i < vec->count; i++) { 13 | printf("vec[%d] = %d\n", i, vec->arr[i]); 14 | } 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-24-dijkstra-route/queue.h: -------------------------------------------------------------------------------- 1 | struct queue_node_t { 2 | struct queue_node_t* next; 3 | void* value; 4 | int priority; 5 | }; 6 | 7 | struct queue_t { 8 | struct queue_node_t* head; 9 | struct queue_node_t* tail; 10 | }; 11 | 12 | struct queue_t* init_queue(); 13 | void queue_add(struct queue_t* q, void* value); 14 | void* queue_remove(struct queue_t* q); -------------------------------------------------------------------------------- /2023-2024/10b/2023-11-20-bst-2/queue.h: -------------------------------------------------------------------------------- 1 | struct queue_t { 2 | struct q_node_t* head; 3 | struct q_node_t* tail; 4 | }; 5 | 6 | struct q_node_t { 7 | struct q_node_t* next; 8 | void* value; 9 | }; 10 | 11 | typedef struct queue_t queue_t; 12 | 13 | queue_t* init_queue(); 14 | int queue_empty(queue_t* q); 15 | void queue_push(queue_t* q, void* value); 16 | void* queue_pop(queue_t* q); -------------------------------------------------------------------------------- /2023-2024/10b/2023-11-27-bst-3/queue.h: -------------------------------------------------------------------------------- 1 | struct queue_t { 2 | struct q_node_t* head; 3 | struct q_node_t* tail; 4 | }; 5 | 6 | struct q_node_t { 7 | struct q_node_t* next; 8 | void* value; 9 | }; 10 | 11 | typedef struct queue_t queue_t; 12 | 13 | queue_t* init_queue(); 14 | int queue_empty(queue_t* q); 15 | void queue_push(queue_t* q, void* value); 16 | void* queue_pop(queue_t* q); -------------------------------------------------------------------------------- /2023-2024/10b/2023-12-11-bst-4/queue.h: -------------------------------------------------------------------------------- 1 | struct queue_t { 2 | struct q_node_t* head; 3 | struct q_node_t* tail; 4 | }; 5 | 6 | struct q_node_t { 7 | struct q_node_t* next; 8 | void* value; 9 | }; 10 | 11 | typedef struct queue_t queue_t; 12 | 13 | queue_t* init_queue(); 14 | int queue_empty(queue_t* q); 15 | void queue_push(queue_t* q, void* value); 16 | void* queue_pop(queue_t* q); -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-13-exam2-solution/ver1/priority_queue.h: -------------------------------------------------------------------------------- 1 | // Implement queue as a single linked list 2 | struct priority_queue_t { 3 | struct priority_queue_t* next; 4 | int value; 5 | int priority; 6 | }; 7 | 8 | struct priority_queue_t* push(struct priority_queue_t* head, int value, int priority); 9 | 10 | int pop(struct priority_queue_t** head); 11 | 12 | void print_queue(struct priority_queue_t* head); 13 | -------------------------------------------------------------------------------- /2024-2025/10a/utils/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef STACK_H 2 | #define STACK_H 3 | 4 | typedef struct StackNode 5 | { 6 | int val; 7 | struct StackNode *next; 8 | } StackNode; 9 | 10 | typedef struct Stack 11 | { 12 | StackNode *top; 13 | } Stack; 14 | 15 | Stack *init_stack(); 16 | void push(Stack *stack, int val); 17 | int pop(Stack *stack); 18 | void clear_stack(Stack *stack); 19 | void print_stack(Stack *stack); 20 | 21 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-06-graph-3/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vector.h" 4 | 5 | void vector_add(struct vector_t* vec, void* value) { 6 | vec->values = realloc(vec->values, (vec->size + 1) * sizeof(void*)); 7 | vec->values[vec->size] = value; 8 | vec->size++; 9 | } 10 | 11 | void* vector_get(struct vector_t* vec, int index) { 12 | if(index > vec->size) return NULL; 13 | return vec->values[index]; 14 | } 15 | -------------------------------------------------------------------------------- /2023-2024/10a/utils/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef VECTOR 2 | #define VECTOR 3 | 4 | typedef struct vector_t 5 | { 6 | int *arr; 7 | unsigned int size; 8 | unsigned int capacity; 9 | } vector_t; 10 | 11 | vector_t *init_vector(); 12 | void push_back(vector_t *, int); 13 | int pop(vector_t *); 14 | void clear(vector_t *); 15 | 16 | int getAt(vector_t *, int); 17 | int getSize(vector_t *); 18 | 19 | void printVector(vector_t *); 20 | #endif -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-11-graph-3/list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct list_t { 4 | struct list_t* next; 5 | void* value; 6 | }; 7 | 8 | typedef struct list_t list_t; 9 | 10 | list_t* init_list(); 11 | 12 | list_t* push_list(list_t* list, void* value); 13 | void* pop_list(list_t** list); 14 | 15 | void* list_get_at(list_t* list, unsigned int index); 16 | int list_length(list_t* list); 17 | 18 | void destroy_list(list_t* list); -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-18-dijkstra-2/list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct list_t { 4 | struct list_t* next; 5 | void* value; 6 | }; 7 | 8 | typedef struct list_t list_t; 9 | 10 | list_t* init_list(); 11 | 12 | list_t* push_list(list_t* list, void* value); 13 | void* pop_list(list_t** list); 14 | 15 | void* list_get_at(list_t* list, unsigned int index); 16 | int list_length(list_t* list); 17 | 18 | void destroy_list(list_t* list); -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-15-hashmap/list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct list_t { 4 | struct list_t* next; 5 | void* value; 6 | }; 7 | 8 | typedef struct list_t list_t; 9 | 10 | list_t* init_list(); 11 | 12 | list_t* push_list(list_t* list, void* value); 13 | void* pop_list(list_t** list); 14 | 15 | void* list_get_at(list_t* list, unsigned int index); 16 | int list_length(list_t* list); 17 | 18 | void destroy_list(list_t* list); -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-29-huffman-coding/list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct list_t { 4 | struct list_t* next; 5 | void* value; 6 | }; 7 | 8 | typedef struct list_t list_t; 9 | 10 | list_t* init_list(); 11 | 12 | list_t* push_list(list_t* list, void* value); 13 | void* pop_list(list_t** list); 14 | 15 | void* list_get_at(list_t* list, unsigned int index); 16 | int list_length(list_t* list); 17 | 18 | void destroy_list(list_t* list); -------------------------------------------------------------------------------- /2023-2024/10b/2024-05-10-huffman-coding-2/list.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct list_t { 4 | struct list_t* next; 5 | void* value; 6 | }; 7 | 8 | typedef struct list_t list_t; 9 | 10 | list_t* init_list(); 11 | 12 | list_t* push_list(list_t* list, void* value); 13 | void* pop_list(list_t** list); 14 | 15 | void* list_get_at(list_t* list, unsigned int index); 16 | int list_length(list_t* list); 17 | 18 | void destroy_list(list_t* list); -------------------------------------------------------------------------------- /2025-2026/10a/utils/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef _VECTOR_H_ 2 | #define _VECTOR_H_ 3 | 4 | typedef struct vector { 5 | int *data; 6 | int size; 7 | int capacity; 8 | } vector; 9 | 10 | vector* init_vector(); 11 | 12 | void push(vector* v, int val); 13 | int pop(vector* v); 14 | 15 | void pushFront(vector* v, int val); 16 | int popFront(vector* v); 17 | 18 | void print_vector(vector* v); 19 | 20 | void free_vector(vector* v); 21 | 22 | #endif -------------------------------------------------------------------------------- /2023-2024/10a/2023-09-29-Exercise_1/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef VECTOR 2 | #define VECTOR 3 | 4 | typedef struct vector_t 5 | { 6 | int *arr; 7 | unsigned int size; 8 | unsigned int capacity; 9 | } vector_t; 10 | 11 | vector_t *init_vector(); 12 | void push_back(vector_t *, int); 13 | int pop(vector_t *); 14 | void clear(vector_t *); 15 | 16 | int getAt(vector_t *, int); 17 | int getSize(vector_t *); 18 | 19 | void printVector(vector_t *); 20 | #endif -------------------------------------------------------------------------------- /2025-2026/10a/2025-09-29-vector/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef _VECTOR_H_ 2 | #define _VECTOR_H_ 3 | 4 | typedef struct vector { 5 | int *data; 6 | int size; 7 | int capacity; 8 | } vector; 9 | 10 | vector* init_vector(); 11 | 12 | void push(vector* v, int val); 13 | int pop(vector* v); 14 | 15 | void pushFront(vector* v, int val); 16 | int popFront(vector* v); 17 | 18 | void print_vector(vector* v); 19 | 20 | void free_vector(vector* v); 21 | 22 | #endif -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-04-Insertion_sort_and_lists/list.h: -------------------------------------------------------------------------------- 1 | #ifndef LIST_H 2 | #define LIST_H 3 | 4 | typedef struct Node 5 | { 6 | int value; 7 | struct Node *next; 8 | } Node; 9 | 10 | typedef struct List 11 | { 12 | Node *head; 13 | } List; 14 | 15 | List *init_list(); 16 | void insertBegin(List *, int); 17 | int getAt(List *, int); 18 | void clear(List *); 19 | int pop(List *); 20 | void printList(List *); 21 | int popFront(List *); 22 | #endif 23 | -------------------------------------------------------------------------------- /2024-2025/10a/2024-10-07-linked_list/main.c: -------------------------------------------------------------------------------- 1 | #include "list.h" 2 | #include 3 | 4 | int main () { 5 | LList* l = init_llist(); 6 | insertEnd(l, 1); 7 | insertEnd(l, 2); 8 | insertEnd(l, 3); 9 | 10 | printList(l); 11 | 12 | int headVal = popBegin(l); 13 | printf("Head: %d\n", headVal); 14 | printList(l); 15 | 16 | printf("At 1: %d\n", getAt(l, 1)->val); 17 | 18 | freeList(l); 19 | 20 | 21 | return 0; 22 | } -------------------------------------------------------------------------------- /2025-2026/10a/utils/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef _STACK_H_ 2 | #define _STACK_H_ 3 | 4 | #include 5 | 6 | typedef struct Node { 7 | int val; 8 | struct Node* next; 9 | } Node; 10 | 11 | typedef struct Stack { 12 | Node* top; 13 | } Stack; 14 | 15 | Node* init_node(int val); 16 | Stack* init_stack(); 17 | void push(Stack* stack, int val); 18 | int pop(Stack* stack); 19 | void printStack(Stack* stack); 20 | bool isEmpty(Stack* stack); 21 | 22 | #endif -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-11-graph-3/graph_utilities.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "graph.h" 4 | 5 | graph_t* init_graph_from_strings(char* lines[]); 6 | 7 | struct span_tree_t { 8 | struct list_t* children; 9 | void* value; 10 | }; 11 | 12 | typedef struct span_tree_t span_tree_t; 13 | 14 | span_tree_t* graph_span_tree(graph_t* graph, char* name); 15 | 16 | 17 | 18 | 19 | 20 | void find_dijkstra_route(graph_t* graph, char* start, char* end); 21 | 22 | -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-18-dijkstra-2/graph_utilities.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "graph.h" 4 | 5 | graph_t* init_graph_from_strings(char* lines[]); 6 | 7 | struct span_tree_t { 8 | struct list_t* children; 9 | void* value; 10 | }; 11 | 12 | typedef struct span_tree_t span_tree_t; 13 | 14 | span_tree_t* graph_span_tree(graph_t* graph, char* name); 15 | 16 | 17 | 18 | 19 | 20 | void find_dijkstra_route(graph_t* graph, char* start, char* end); 21 | 22 | -------------------------------------------------------------------------------- /2025-2026/10a/utils/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | typedef struct Node 5 | { 6 | int val; 7 | struct Node *next; 8 | } Node; 9 | 10 | typedef struct Queue 11 | { 12 | Node *front; 13 | Node *rear; 14 | } Queue; 15 | 16 | Node *create_node(int val); 17 | Queue *init_queue(); 18 | void enqueue(Queue *queue, int val); 19 | int dequeue(Queue *queue); 20 | void clear_queue(Queue *queue); 21 | void print_queue(Queue *queue); 22 | 23 | #endif -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-15-stack/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef _STACK_H_ 2 | #define _STACK_H_ 3 | 4 | #include 5 | 6 | typedef struct Node { 7 | int val; 8 | struct Node* next; 9 | } Node; 10 | 11 | typedef struct Stack { 12 | Node* top; 13 | } Stack; 14 | 15 | Node* init_node(int val); 16 | Stack* init_stack(); 17 | void push(Stack* stack, int val); 18 | int pop(Stack* stack); 19 | void printStack(Stack* stack); 20 | bool isEmpty(Stack* stack); 21 | 22 | #endif -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-25-skip-list/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "skip_list.h" 3 | 4 | int main() 5 | { 6 | SkipList *list = init_list(); 7 | 8 | sl_insert(list, 1); 9 | sl_insert(list, 4); 10 | sl_insert(list, 3); 11 | sl_insert(list, -10); 12 | sl_insert(list, -5); 13 | sl_insert(list, 137); 14 | sl_insert(list, 100); 15 | sl_insert(list, 23); 16 | sl_insert(list, 5); 17 | 18 | printList(list); 19 | clear(list); 20 | } 21 | -------------------------------------------------------------------------------- /2024-2025/10v/2024_12_11 heap/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef HEAP_T 2 | #define HEAP_T 3 | 4 | typedef struct vector { 5 | int* arr; 6 | int size; 7 | int capacity; 8 | } vector; 9 | 10 | 11 | vector* init_vector(int initialCapacity); 12 | 13 | void push(vector* v, int val); 14 | 15 | int pop(vector* v); 16 | 17 | int getAt(vector *v, int i); 18 | 19 | void clear_vector(vector* v); 20 | 21 | void free_vector(vector* v); 22 | 23 | void print_vector(vector* v); 24 | 25 | #endif -------------------------------------------------------------------------------- /2024-2025/10a/utils/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | typedef struct QNode 5 | { 6 | int val; 7 | struct QNode *next; 8 | } QNode; 9 | 10 | typedef struct Queue 11 | { 12 | QNode *front; 13 | QNode *rear; 14 | } Queue; 15 | 16 | 17 | QNode *create_qnode(int val); 18 | Queue *init_queue(); 19 | void enqueue(Queue *queue, int val); 20 | int dequeue(Queue *queue); 21 | void clear_queue(Queue *queue); 22 | void print_queue(Queue *queue); 23 | 24 | #endif -------------------------------------------------------------------------------- /2024-2025/10v/2024_10_18 SkipList/skiplist.h: -------------------------------------------------------------------------------- 1 | #ifndef SKIPLIST_H 2 | #define SKIPLIST_H 3 | 4 | #define MAX_LEVEL 4 5 | 6 | struct Node { 7 | int val; 8 | struct Node* next[MAX_LEVEL]; 9 | }; 10 | 11 | typedef struct Node Node; 12 | Node* createNode(int val); 13 | 14 | typedef struct SkipList { 15 | Node* head; 16 | } SkipList; 17 | 18 | SkipList init(); 19 | void insert(SkipList* list, int val); 20 | void printList(SkipList* list); 21 | 22 | void release(SkipList* list); 23 | 24 | 25 | #endif -------------------------------------------------------------------------------- /2024-2025/10v/2024_11_27 avl/avlTree.h: -------------------------------------------------------------------------------- 1 | #ifndef AVLTREE_H 2 | #define AVLTREE_H 3 | 4 | struct AVLNode { 5 | struct AVLNode* left; 6 | struct AVLNode* right; 7 | int val; 8 | int height; 9 | }; 10 | 11 | typedef struct AVLNode AVLNode; 12 | 13 | AVLNode* createNode(int val); 14 | AVLNode* insert(AVLNode* node, int val); 15 | void printInOrder(AVLNode* node); 16 | AVLNode* rotateLeft(AVLNode* node); 17 | AVLNode* rotateRight(AVLNode* node); 18 | void updateHeight(AVLNode* node); 19 | 20 | #endif -------------------------------------------------------------------------------- /2024-2025/10a/2025-01-10-rb-tree/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "tree.h" 3 | 4 | int main() { 5 | Node* root = NULL; 6 | bst_insert(&root, 5); 7 | bst_insert(&root, 10); 8 | bst_insert(&root, 20); 9 | bst_insert(&root, 0); 10 | bst_insert(&root, 16); 11 | bst_insert(&root, 7); 12 | bst_insert(&root, 30); 13 | bst_insert(&root, -10); 14 | bst_insert(&root, 100); 15 | 16 | printTree(root); 17 | printf("\n"); 18 | printTreeInorder(root); 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /2024-2025/10v/2025_02_25 graph traversal/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H 2 | #define QUEUE_H 3 | 4 | typedef struct QNode 5 | { 6 | int val; 7 | struct QNode *next; 8 | } QNode; 9 | 10 | typedef struct Queue 11 | { 12 | QNode *front; 13 | QNode *rear; 14 | } Queue; 15 | 16 | 17 | QNode* createQnode(int val); 18 | Queue* initQueue(); 19 | int isEmpty(Queue* queue); 20 | void push(Queue* queue, int val); 21 | int pop(Queue* queue); 22 | void clearQueue(Queue* queue); 23 | void printQueue(Queue* queue); 24 | 25 | #endif -------------------------------------------------------------------------------- /2024-2025/10v/2025_04_15 hashmap/ransomNode.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int canMake(char* ransomNote, char* magazine) { 5 | int letterOcurrances[26] = {0}; 6 | 7 | for (int i = 0; ransomNote[i] != '\0'; i++) { 8 | letterOcurrances[ransomNote[i] - 'a']++; 9 | } 10 | 11 | for (int i = 0; magazine[i] != '\0'; i++) { 12 | if (--letterOcurrances[magazine[i] - 'a'] < 0) { 13 | return 0; 14 | } 15 | } 16 | return 1; 17 | } 18 | 19 | int main() { 20 | 21 | } -------------------------------------------------------------------------------- /2024-2025/10a/2025-01-10-rb-tree/tree.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_H 2 | #define TREE_H 3 | 4 | enum Color { 5 | RED, 6 | BLACK 7 | } typedef Color; 8 | 9 | struct Node { 10 | int val; 11 | Color color; 12 | struct Node* left; 13 | struct Node* right; 14 | struct Node* parent; 15 | } typedef Node; 16 | 17 | Node* create_node(int); 18 | void bst_insert(Node**, int); 19 | void printTree(Node*); 20 | void left_rotation(Node**, Node *x); 21 | void right_rotation(Node**, Node *y); 22 | void printTreeInorder(Node* root); 23 | #endif -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-06-list/list.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIST_H_ 2 | #define _LIST_H_ 3 | 4 | typedef struct Node { 5 | int val; 6 | struct Node* next; 7 | struct Node* prev; 8 | } Node; 9 | 10 | typedef struct LList { 11 | Node* head; 12 | Node* tail; 13 | } LList; 14 | 15 | Node* init_node(int val); 16 | LList* init_llist(); 17 | void insertHead(LList* list, int val); 18 | int popHead(LList* list); 19 | void printList(LList* list); 20 | void printListReverse(LList* list); 21 | int getAt(LList* list, int index); 22 | 23 | #endif -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-15-hashmap/map.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct map_t { 4 | struct list_t** hash_arr; 5 | unsigned int hash_arr_size; 6 | unsigned int size; 7 | }; 8 | 9 | struct map_node_t { 10 | char* key; 11 | void* value; 12 | }; 13 | 14 | typedef struct map_t map_t; 15 | 16 | map_t* init_map(unsigned int size); 17 | 18 | int map_has_key(map_t* map, char* key); 19 | 20 | void map_add(map_t* map, char* key, void* value); 21 | void map_remove(map_t* map, char* key); 22 | void* map_get(map_t* map, char* key); -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-29-huffman-coding/map.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct map_t { 4 | struct list_t** hash_arr; 5 | unsigned int hash_arr_size; 6 | unsigned int size; 7 | }; 8 | 9 | struct map_node_t { 10 | char* key; 11 | void* value; 12 | }; 13 | 14 | typedef struct map_t map_t; 15 | 16 | map_t* init_map(unsigned int size); 17 | 18 | int map_has_key(map_t* map, char* key); 19 | 20 | void map_add(map_t* map, char* key, void* value); 21 | void map_remove(map_t* map, char* key); 22 | void* map_get(map_t* map, char* key); -------------------------------------------------------------------------------- /2023-2024/10b/2024-05-10-huffman-coding-2/map.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct map_t { 4 | struct list_t** hash_arr; 5 | unsigned int hash_arr_size; 6 | unsigned int size; 7 | }; 8 | 9 | struct map_node_t { 10 | char* key; 11 | void* value; 12 | }; 13 | 14 | typedef struct map_t map_t; 15 | 16 | map_t* init_map(unsigned int size); 17 | 18 | int map_has_key(map_t* map, char* key); 19 | 20 | void map_add(map_t* map, char* key, void* value); 21 | void map_remove(map_t* map, char* key); 22 | void* map_get(map_t* map, char* key); -------------------------------------------------------------------------------- /2024-2025/10v/2025_04_23 huffman/pqueue.h: -------------------------------------------------------------------------------- 1 | #ifndef PQUEUE_H 2 | #define PQUEUE_H 3 | 4 | #define MAX_PQ_NODES 1000 5 | 6 | typedef struct PQNode { 7 | float key; 8 | void *data; 9 | } PQNode; 10 | 11 | typedef struct PQueue { 12 | PQNode *arr[MAX_PQ_NODES]; 13 | int size; 14 | } PQueue; 15 | 16 | PQueue *init_pq(); 17 | PQNode *init_pq_node(void *data, float key); 18 | void swap(PQNode **a, PQNode **b); 19 | void siftDown(PQueue *pq, int i); 20 | PQNode *deleteMin(PQueue *pq); 21 | void pqInsert(PQueue *pq, void *data, float key); 22 | 23 | #endif -------------------------------------------------------------------------------- /2024-2025/10v/2024_11_13 set and treeSet/TreeSet/treeSet.h: -------------------------------------------------------------------------------- 1 | #ifndef TREESET_T 2 | #define TREESET_T 3 | 4 | struct TreeNode { 5 | struct TreeNode* left; 6 | struct TreeNode* right; 7 | int val; 8 | }; 9 | 10 | typedef struct TreeNode TreeNode; 11 | 12 | TreeNode* initTreeTreeNode(int val); 13 | 14 | int treeSetContains(TreeNode* set, int val); 15 | 16 | TreeNode* treeSetAdd(TreeNode* set, int val); 17 | void treeSetAdd2(TreeNode** set, int val); 18 | 19 | unsigned treeSetHeight(TreeNode* set); 20 | 21 | void printTreeSet(TreeNode* set); 22 | 23 | #endif -------------------------------------------------------------------------------- /2024-2025/10v/2024_10_18 SkipList/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "skiplist.h" 6 | 7 | int main() { 8 | srand(time(NULL)); 9 | SkipList myList = init(); 10 | 11 | insert(&myList, 1); 12 | insert(&myList, 1); 13 | insert(&myList, 3); 14 | insert(&myList, 5); 15 | insert(&myList, 8); 16 | insert(&myList, 10); 17 | insert(&myList, 15); 18 | printList(&myList); 19 | insert(&myList, 6); 20 | printf("\n\n\n"); 21 | printList(&myList); 22 | 23 | release(&myList); 24 | } -------------------------------------------------------------------------------- /2023-2024/10a/utils/graph.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPH_H 2 | #define GRAPH_H 3 | 4 | typedef struct VertexNode 5 | { 6 | int val; 7 | int weight; 8 | struct VertexNode *next; 9 | } VertexNode; 10 | 11 | typedef struct Graph 12 | { 13 | int numVertices; 14 | VertexNode **adjList; 15 | } Graph; 16 | 17 | VertexNode *init_node(int val, int weight); 18 | Graph *init_graph(int numVertices); 19 | void addEdgeDirectional(Graph *graph, int from, int to, int weigth); 20 | void addEdge(Graph *graph, int from, int to, int weigth); 21 | void printGraph(Graph *graph); 22 | 23 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2022-09-21-revision-2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../2022-09-21-revision-2/functions.h" 5 | 6 | int main() { 7 | printf("%d\n", foo()); 8 | bar(); 9 | 10 | char *a = (char*)malloc(4 * sizeof(char)); 11 | int *b = (int*)a; 12 | 13 | for(int i = 0; i < 4; i++) { 14 | a[i] = 'a' + i; 15 | printf("%d -> %c\n", i, a[i]); 16 | } 17 | 18 | printf("%d\n", *b); 19 | 20 | a = realloc(a, 10 * sizeof(char)); 21 | 22 | a = calloc(5, sizeof(char)); 23 | 24 | free(a); 25 | a = NULL; 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-13-exam2-solution/ver1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "priority_queue.h" 4 | 5 | int get_random(int min, int max) { 6 | return rand() % (max - min) + min; 7 | } 8 | 9 | void test_queue() { 10 | struct priority_queue_t* q = NULL; 11 | 12 | for(int i = 0; i < 100000; i++) 13 | q = push( 14 | q, 15 | get_random(0, 10000), 16 | get_random(1, 100) 17 | ); 18 | 19 | for(int i = 0; i < 50000; i++) 20 | pop(&q); 21 | 22 | print_queue(q); 23 | } 24 | 25 | int main() { 26 | test_queue(); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-04-Insertion_sort_and_lists/list_preview.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "list.h" 3 | 4 | int main() 5 | { 6 | List *l = init_list(); 7 | printList(l); 8 | insertBegin(l, 1); 9 | popFront(l); 10 | printList(l); 11 | 12 | insertBegin(l, 2); 13 | insertBegin(l, 3); 14 | insertBegin(l, 4); 15 | 16 | int val = popFront(l); 17 | printf("popped = %d\n", val); 18 | printList(l); 19 | 20 | val = pop(l); 21 | printf("popped = %d\n", val); 22 | printList(l); 23 | 24 | clear(l); 25 | 26 | return 0; 27 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-11-29-tree4/queue.h: -------------------------------------------------------------------------------- 1 | typedef struct Node 2 | { 3 | int val; 4 | int height; 5 | struct Node *left; 6 | struct Node *right; 7 | } Node; 8 | 9 | typedef struct QueueNode 10 | { 11 | Node *val; 12 | struct QueueNode *next; 13 | } QueueNode; 14 | 15 | typedef struct Queue 16 | { 17 | QueueNode *front; 18 | QueueNode *rear; 19 | } Queue; 20 | 21 | QueueNode *create_node(Node *val); 22 | 23 | Queue *init_queue(); 24 | void enqueue(Queue *queue, Node *val); 25 | 26 | Node *dequeue(Queue *queue); 27 | 28 | void clear_queue(Queue *queue); -------------------------------------------------------------------------------- /2023-2024/10a/utils/graph_h.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPH_H 2 | #define GRAPH_H 3 | #include "hash.h" 4 | 5 | typedef struct VertexNode 6 | { 7 | char *val; 8 | double weight; 9 | struct VertexNode *next; 10 | } VertexNode; 11 | 12 | typedef struct Graph 13 | { 14 | HashMap *adjList; 15 | } Graph; 16 | 17 | VertexNode *init_node(char *val, double weight); 18 | Graph *init_graph(); 19 | void addEdgeDirectional(Graph *graph, char *from, char *to, double weight); 20 | void addEdge(Graph *graph, char *from, char *to, double weight); 21 | void printGraph(Graph *graph); 22 | 23 | #endif -------------------------------------------------------------------------------- /2024-2025/10b/2025-05-27-des-1/helpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // https://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format 4 | // Assumes little endian 5 | void printBits(size_t const size, void const * const ptr) 6 | { 7 | unsigned char *b = (unsigned char*) ptr; 8 | unsigned char byte; 9 | int i, j; 10 | 11 | for (i = size-1; i >= 0; i--) { 12 | for (j = 7; j >= 0; j--) { 13 | byte = (b[i] >> j) & 1; 14 | printf("%u", byte); 15 | } 16 | } 17 | puts(""); 18 | } 19 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-13-exam2-solution/ver2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "priority_queue.h" 4 | 5 | int get_random(int min, int max) { 6 | return rand() % (max - min) + min; 7 | } 8 | 9 | void test_queue() { 10 | struct priority_queue_t* q = init_queue(); 11 | 12 | for(int i = 0; i < 100000; i++) 13 | push_queue( 14 | q, 15 | get_random(0, 10000), 16 | get_random(1, 100) 17 | ); 18 | 19 | for(int i = 0; i < 50000; i++) 20 | pop_queue(q); 21 | 22 | print_queue(q); 23 | } 24 | 25 | int main() { 26 | test_queue(); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /2024-2025/10a/2024-10-14-stack/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef H_STACK_ 2 | #define H_STACK_ 3 | 4 | typedef struct Node { 5 | int val; 6 | struct Node* next; 7 | } Node; 8 | 9 | typedef struct Stack { 10 | Node* top; 11 | } Stack; 12 | 13 | Node* init_node(int val); 14 | Stack* init_stack(); 15 | 16 | void push(Stack* l, int val); 17 | int pop(Stack* l); 18 | int isEmpty(Stack *); 19 | //void printList(LList *l); 20 | // void clear(Stack* l); 21 | // void freeList(LList* l); 22 | // void insertEnd(LList* l, int val); 23 | // int popEnd(LList* l); 24 | // void insertionSort(LList* l); 25 | 26 | #endif -------------------------------------------------------------------------------- /2023-2024/10a/utils/pqueue.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PQUEUE_H 3 | #define PQUEUE_H 4 | 5 | #define MAX_PQ_NODES 1000 6 | 7 | typedef struct PQNode 8 | { 9 | float key; 10 | void *data; 11 | } PQNode; 12 | 13 | typedef struct PQueue 14 | { 15 | PQNode *arr[MAX_PQ_NODES]; 16 | int size; 17 | } PQueue; 18 | 19 | PQueue *init_pq(); 20 | PQNode *createPQNode(void *data, int key); 21 | void swap(PQNode **a, PQNode **b); 22 | void siftDown(PQueue *pq, int i); 23 | PQNode *deleteMin(PQueue *pq); 24 | PQNode *init_pq_node(void *data, float key); 25 | void pqInsert(PQueue *pq, void *data, float key); 26 | 27 | #endif -------------------------------------------------------------------------------- /2024-2025/10v/2024_10_11 DoublyLinkedLists/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dLinkedList.h" 3 | 4 | int main() { 5 | Dlist myList = initList(); 6 | pushBack(&myList, 1); 7 | pushBack(&myList, 2); 8 | pushBack(&myList, 3); 9 | pushBack(&myList, 4); 10 | pushBack(&myList, 5); 11 | printf("%d\n", getAt(&myList, 3)->val); 12 | pushAt(&myList, 10, 3); 13 | popAt(&myList, 3); 14 | printFromHead(&myList); 15 | popBack(&myList); 16 | popBack(&myList); 17 | popBack(&myList); 18 | popBack(&myList); 19 | popBack(&myList); 20 | printFromHead(&myList); 21 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-07-bst-3/quicksort.c: -------------------------------------------------------------------------------- 1 | void swap(int *a, int *b) { 2 | int c = *a; 3 | *a = *b; 4 | *b = c; 5 | } 6 | 7 | void quick_sort(int *arr, unsigned int size) { 8 | if(size < 2) return; 9 | 10 | int pivot_index = size-1; 11 | 12 | for(int i = 0; i < pivot_index; i++) { 13 | if(arr[i] > arr[pivot_index]) { 14 | swap(arr + i, arr + pivot_index - 1); 15 | swap(arr + pivot_index-1, arr+pivot_index); 16 | pivot_index--; 17 | i--; 18 | } 19 | } 20 | quick_sort(arr, pivot_index); 21 | 22 | quick_sort(arr + pivot_index + 1, size - pivot_index - 1); 23 | } 24 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-19-bst-4/quicksort.c: -------------------------------------------------------------------------------- 1 | void swap(int *a, int *b) { 2 | int c = *a; 3 | *a = *b; 4 | *b = c; 5 | } 6 | 7 | void quick_sort(int *arr, unsigned int size) { 8 | if(size < 2) return; 9 | 10 | int pivot_index = size-1; 11 | 12 | for(int i = 0; i < pivot_index; i++) { 13 | if(arr[i] > arr[pivot_index]) { 14 | swap(arr + i, arr + pivot_index - 1); 15 | swap(arr + pivot_index-1, arr+pivot_index); 16 | pivot_index--; 17 | i--; 18 | } 19 | } 20 | quick_sort(arr, pivot_index); 21 | 22 | quick_sort(arr + pivot_index + 1, size - pivot_index - 1); 23 | } 24 | -------------------------------------------------------------------------------- /2024-2025/10a/utils/graph_h.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPH_H_H 2 | #define GRAPH_H_H 3 | 4 | #include "hashmap.h" 5 | typedef struct Vertex { 6 | char* val; 7 | double weight; 8 | struct Vertex* next; 9 | } Vertex; 10 | /* 11 | 0: (2, 10) -> (3, 10) -> (2, 15) 12 | */ 13 | typedef struct Graph { 14 | HashMap* adjList; 15 | } Graph; 16 | 17 | Vertex* init_vertex(char* val, double weight); 18 | Graph* init_graph(); 19 | 20 | void addEdgeDirectional(Graph*graph, char* from, char* to, double weight); 21 | void addEdge(Graph* graph, char* from, char* to, double weight); 22 | 23 | void printGraph(Graph *graph); 24 | 25 | #endif -------------------------------------------------------------------------------- /2024-2025/10a/utils/hashmap.h: -------------------------------------------------------------------------------- 1 | #ifndef _HASHMAP_H_ 2 | #define _HASHMAP_H_ 3 | 4 | #define HASHMAP_SIZE 16 5 | 6 | typedef struct EntryNode { 7 | char* key; 8 | void* val; 9 | struct EntryNode* next; 10 | } EntryNode; 11 | 12 | EntryNode* init_entry(char* key, void* val); 13 | typedef struct HashMap { 14 | EntryNode** entries; 15 | } HashMap; 16 | 17 | HashMap* init_hashmap(); 18 | int hash(char* key); 19 | void* get(HashMap* hashmap, char* key); 20 | void set(HashMap* hashmap, char* key, void* val); 21 | void setInt(HashMap *hash_map, char *key, int val); 22 | int getInt(HashMap *hash_map, char *key); 23 | #endif -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-06-list/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "list.h" 4 | 5 | 6 | void allSums(Node* current, int currentSum) { 7 | if (current == NULL) { 8 | printf("%d\n", currentSum); 9 | return; 10 | } 11 | 12 | allSums(current->next, currentSum+current->val); 13 | allSums(current->next, currentSum); 14 | } 15 | 16 | 17 | int main() { 18 | LList* list = init_llist(); 19 | insertHead(list, 5); 20 | insertHead(list, 6); 21 | insertHead(list, 7); 22 | printList(list); 23 | allSums(list->head, 0); 24 | 25 | 26 | return 0; 27 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-09-26-revision-3/main.c: -------------------------------------------------------------------------------- 1 | //#include 2 | #include 3 | 4 | #include "list.h" 5 | 6 | int main() { 7 | /*struct list_node_t n1 = {5, NULL}; 8 | struct list_node_t n2; 9 | n2.value = 7; 10 | n2.next = NULL; 11 | 12 | //printf("%d\n", n1.value); 13 | 14 | struct list_node_t n3 = {18, NULL}; 15 | 16 | n1.next = &n2; 17 | n2.next = &n3; 18 | 19 | print_list(&n1);*/ 20 | 21 | struct list_node_t *list = NULL; 22 | 23 | list = push_back(list, 10); 24 | list = push_back(list, 15); 25 | list = push_back(list, 20); 26 | 27 | print_list(list); 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /2024-2025/10a/2024-11-25-avl/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "tree.h" 4 | 5 | int main() { 6 | Node* root = create_node(10); 7 | // bst_insert(root, 5); 8 | // bst_insert(root, 1); 9 | for (int i = 11; i < 20; i++ ) { 10 | root = bst_insert(root, i); 11 | } 12 | 13 | printf("Height %d\n", root->height); 14 | 15 | // printTree(root); 16 | // printf("Height is: %d\n", root->height); 17 | // root = right_rotation(root); 18 | // printf("\n"); 19 | // printf("Height is: %d\n", root->height); 20 | // printTree(root); 21 | 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-10-graph-4/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vector.h" 4 | 5 | struct vector_t* vector_init() { 6 | struct vector_t* new_vec = malloc(sizeof(struct vector_t)); 7 | 8 | new_vec->size = 0; 9 | new_vec->values = NULL; 10 | 11 | return new_vec; 12 | } 13 | 14 | void vector_add(struct vector_t* vec, void* value) { 15 | vec->values = realloc(vec->values, (vec->size + 1) * sizeof(void*)); 16 | vec->values[vec->size] = value; 17 | vec->size++; 18 | } 19 | 20 | void* vector_get(struct vector_t* vec, int index) { 21 | if(index > vec->size) return NULL; 22 | return vec->values[index]; 23 | } 24 | -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-17-dijkstra/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vector.h" 4 | 5 | struct vector_t* vector_init() { 6 | struct vector_t* new_vec = malloc(sizeof(struct vector_t)); 7 | 8 | new_vec->size = 0; 9 | new_vec->values = NULL; 10 | 11 | return new_vec; 12 | } 13 | 14 | void vector_add(struct vector_t* vec, void* value) { 15 | vec->values = realloc(vec->values, (vec->size + 1) * sizeof(void*)); 16 | vec->values[vec->size] = value; 17 | vec->size++; 18 | } 19 | 20 | void* vector_get(struct vector_t* vec, int index) { 21 | if(index > vec->size) return NULL; 22 | return vec->values[index]; 23 | } 24 | -------------------------------------------------------------------------------- /2023-2024/10b/2023-11-03-recursion-recap/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(int arg) { 4 | //return arg + 2; 5 | 6 | // int res = 0; 7 | 8 | // for(int i = 1; i < arg; i++) 9 | // res += i; 10 | 11 | // return res; 12 | 13 | printf("foo(%d)\n", arg); 14 | if(arg == 0) return 0; 15 | 16 | int res = arg + foo(arg-1); 17 | printf("food(%d) = %d\n", arg, res); 18 | return res; 19 | } 20 | 21 | int main() { 22 | printf("%d\n", foo(0)); 23 | puts(""); 24 | printf("%d\n", foo(1)); 25 | puts(""); 26 | printf("%d\n", foo(5)); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /2024-2025/10a/2024-10-07-linked_list/list.h: -------------------------------------------------------------------------------- 1 | #ifndef H_LIST_ 2 | #define H_LIST_ 3 | 4 | typedef struct Node { 5 | int val; 6 | struct Node* next; 7 | struct Node* prev; 8 | } Node; 9 | 10 | typedef struct LList { 11 | Node* head; 12 | Node * tail; 13 | } LList; 14 | 15 | Node* init_node(int val); 16 | LList* init_llist(); 17 | 18 | void insertBegin(LList* l, int val); 19 | int popBegin(LList* l); 20 | Node* getAt(LList* l, int i); 21 | 22 | void printList(LList *l); 23 | void clear(LList* l); 24 | void freeList(LList* l); 25 | void insertEnd(LList* l, int val); 26 | int popEnd(LList* l); 27 | void insertionSort(LList* l); 28 | 29 | #endif -------------------------------------------------------------------------------- /2023-2024/10a/utils/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | #define HASH_SIZE 8 4 | 5 | // Chaining implementation of a hash map 6 | typedef struct EntryNode 7 | { 8 | char *key; 9 | void *val; 10 | struct EntryNode *next; 11 | } EntryNode; 12 | 13 | typedef struct HashMap 14 | { 15 | EntryNode **array; 16 | } HashMap; 17 | 18 | EntryNode *init_entry(char *key, void *val); 19 | HashMap *init_hash_map(); 20 | int hash(char *key); 21 | void set(HashMap *hash_map, char *key, void *val); 22 | void *get(HashMap *hash_map, char *key); 23 | void setInt(HashMap *hash_map, char *key, int val); 24 | int getInt(HashMap *hash_map, char *key); 25 | 26 | #endif -------------------------------------------------------------------------------- /2024-2025/10a/utils/pqueue.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PQUEUE_H 3 | #define PQUEUE_H 4 | 5 | // should be dynamic but to make it a bit easier for us 6 | #define MAX_PQ_NODES 1000 7 | 8 | typedef struct PQNode 9 | { 10 | float key; 11 | void *data; 12 | } PQNode; 13 | 14 | typedef struct PQueue 15 | { 16 | PQNode *arr[MAX_PQ_NODES]; 17 | int size; 18 | } PQueue; 19 | 20 | PQueue *init_pq(); 21 | PQNode *createPQNode(void *data, int key); 22 | void swap(PQNode **a, PQNode **b); 23 | void siftDown(PQueue *pq, int i); 24 | PQNode *deleteMin(PQueue *pq); 25 | PQNode *init_pq_node(void *data, float key); 26 | void pqInsert(PQueue *pq, void *data, float key); 27 | 28 | #endif -------------------------------------------------------------------------------- /2023-2024/10b/2023-09-25-intro-2/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vector.h" 4 | 5 | vector_t* init_vector() { 6 | vector_t* vec = (vector_t*)malloc(sizeof(vector_t)); 7 | 8 | vec->count = 0; 9 | vec->arr = NULL; 10 | 11 | return vec; 12 | } 13 | 14 | void push_vector(vector_t* vec, int value) { 15 | vec->arr = realloc( 16 | vec->arr, 17 | sizeof(int) * (vec->count + 1) 18 | ); 19 | vec->arr[vec->count++] = value; 20 | } 21 | 22 | int vector_get_at(vector_t* vec, unsigned int index) { 23 | if(vec->count <= index) { 24 | return -1; 25 | } 26 | 27 | return vec->arr[index]; 28 | } -------------------------------------------------------------------------------- /2024-2025/10a/utils/graph.h: -------------------------------------------------------------------------------- 1 | #ifndef GRAPH_H 2 | #define GRAPH_H 3 | 4 | #include 5 | #include 6 | 7 | typedef struct Vertex { 8 | int val; 9 | double weight; 10 | struct Vertex* next; 11 | } Vertex; 12 | /* 13 | 0: (2, 10) -> (3, 10) -> (2, 15) 14 | */ 15 | typedef struct Graph { 16 | int numVertices; 17 | Vertex **adjList; 18 | } Graph; 19 | 20 | Vertex* init_vertex(int val, double weight); 21 | 22 | Graph* init_graph(int numVertices); 23 | 24 | void addEdgeDirectional(Graph*graph, int from, int to, double weight); 25 | void addEdge(Graph* graph, int from, int to, double weight); 26 | 27 | void printGraph(Graph *graph); 28 | 29 | 30 | #endif -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-15-stack/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | int main() { 6 | char* str = "()()()((())"; 7 | Stack* stack = init_stack(); 8 | 9 | for (int i = 0; i < strlen(str); i++) { 10 | if (str[i] == '(') { 11 | push(stack, 1); 12 | } else { 13 | if (isEmpty(stack)) { 14 | printf("not balanced\n"); 15 | break; 16 | } 17 | pop(stack); 18 | } 19 | } 20 | 21 | if (isEmpty(stack)) { 22 | printf("balanced\n"); 23 | } else { 24 | printf("not balanced\n"); 25 | } 26 | 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /2024-2025/10b/2024-10-02-linked-list/example.c: -------------------------------------------------------------------------------- 1 | struct list_node_t { 2 | int value; 3 | struct list_node_t* next; 4 | }; 5 | 6 | struct list_node_t* create_node(int value) { 7 | struct list_node_t* new_node = malloc(..); 8 | new_node->value = value; 9 | new_node->next = NULL; 10 | 11 | return new_node; 12 | } 13 | 14 | struct list_node_t* push_front(struct list_node_t* head, int value) { 15 | struct list_node_t* new_node = create_node(value); 16 | 17 | new_node->next = head; 18 | head = new_node; 19 | 20 | return head; 21 | } 22 | 23 | struct list_node_t* my_list = ...; 24 | my_list = push_front(my_list, 5); 25 | 26 | void push_back(struct list_node_t* head, int value); -------------------------------------------------------------------------------- /2023-2024/10a/utils/dsu.c: -------------------------------------------------------------------------------- 1 | #include "dsu.h" 2 | 3 | int Find(Subset *subsets, int i) 4 | { 5 | if (subsets[i].parent == i) 6 | { 7 | return i; 8 | } 9 | 10 | return Find(subsets, subsets[i].parent); 11 | } 12 | 13 | void Union(Subset *subsets, int src, int dest) 14 | { 15 | int root1 = Find(subsets, src); 16 | int root2 = Find(subsets, dest); 17 | 18 | if (subsets[root1].rank < subsets[root2].rank) 19 | { 20 | subsets[root1].parent = root2; 21 | } 22 | else if (subsets[root1].rank > subsets[root2].rank) 23 | { 24 | subsets[root2].parent = root1; 25 | } 26 | else 27 | { 28 | subsets[root2].parent = root1; 29 | subsets[root1].rank++; 30 | } 31 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-02-19-graph-1/graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "list.h" 4 | 5 | struct graph_node_t { 6 | char* name; 7 | list_t* edges; 8 | }; 9 | 10 | struct graph_t { 11 | int size; 12 | list_t* nodes; 13 | }; 14 | 15 | typedef struct graph_node_t graph_node_t; 16 | typedef struct graph_t graph_t; 17 | 18 | graph_node_t* init_graph_node(char* name); 19 | graph_t* init_graph(); 20 | 21 | void connect_nodes(graph_node_t* node1, graph_node_t* node2); 22 | 23 | graph_node_t* find_node_by_name(graph_t* graph, char* name); 24 | 25 | graph_node_t* add_graph_node(graph_t* graph, char* name); 26 | 27 | void print_graph(graph_t* graph); 28 | 29 | graph_t* init_graph_from_strings(char* lines[]); -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-13-Excersise/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../utils/vector.h" 3 | 4 | int isPalindromeStep(vector_t *v, int start, int end) 5 | { 6 | if (start >= end) 7 | { 8 | return 1; 9 | } 10 | 11 | if (getAt(v, start) == getAt(v, end)) 12 | { 13 | return isPalindromeStep(v, start + 1, end - 1); 14 | } 15 | 16 | return 0; 17 | } 18 | 19 | int isPalindrome(vector_t *v) 20 | { 21 | return isPalindromeStep(v, 0, getSize(v) - 1); 22 | } 23 | 24 | int main() 25 | { 26 | vector_t *v = init_vector(); 27 | 28 | push_back(v, 1); 29 | push_back(v, 2); 30 | push_back(v, 5); 31 | push_back(v, 3); 32 | push_back(v, 1); 33 | 34 | printf("%d", isPalindrome(v)); 35 | } -------------------------------------------------------------------------------- /2024-2025/10b/2024-09-25-intro-1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | int main() { 5 | int arr1[5]; 6 | // int* arr2[5]; ??? 7 | int arr3[5] = {1,2,3}; 8 | 9 | int* ptr1 = NULL; 10 | if(ptr1 == NULL) { 11 | printf("ptr1 is empty\n"); 12 | // ... 13 | } 14 | 15 | for(int i = 0; i < 5; i++) 16 | arr1[i] = i + 10; 17 | for(int i = 0; i < 5; i++) 18 | printf("arr1[%d] = %d\n", i, arr1[i]); 19 | 20 | // for(int* i = arr1; ???; i++) 21 | // printf("arr1[%d] = %d\n", ???, *i); 22 | 23 | printf("%p %d %d\n", arr1, arr1[0], *arr1); 24 | for(int i = 0; i < 5; i++) 25 | printf("%p %p %d %d\n", &(arr1[i]), arr1 + i, arr1[i], *(arr1 + i)); 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-02-19-graph-1/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = NULL; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | void push_list(list_t* list, void* value) { 15 | if(list->next == NULL) { 16 | list->next = init_list(); 17 | list->next->value = value; 18 | } else { 19 | push_list(list->next, value); 20 | } 21 | } 22 | 23 | void* list_get_at( 24 | list_t* list, 25 | unsigned int index 26 | ) { 27 | list_t* curr = list; 28 | int i = 0; 29 | 30 | while(inext; 32 | i++; 33 | } 34 | 35 | return curr->value; 36 | } -------------------------------------------------------------------------------- /2024-2025/10v/Kontrolno 1 example/dLinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | 4 | struct Node { 5 | struct Node* next; 6 | struct Node* prev; 7 | int val; 8 | }; 9 | 10 | typedef struct Node Node; 11 | 12 | typedef struct Dlist { 13 | struct Node* head; 14 | struct Node* tail; 15 | int size; 16 | } Dlist; 17 | 18 | Dlist initList(); 19 | 20 | Node* createNode(int val); 21 | 22 | void pushFront(Dlist* list, int val); 23 | void pushBack(Dlist* list, int val); 24 | void pushAt(Dlist* list, int val, int idx); 25 | 26 | void popFront(Dlist* list); 27 | void popBack(Dlist* list); 28 | void popAt(Dlist* list, int idx); 29 | 30 | Node* getAt(Dlist* list, int idx); 31 | 32 | void printFromHead(Dlist* list); 33 | void printFromTail(Dlist* list); 34 | 35 | void release(Dlist* list); 36 | 37 | #endif -------------------------------------------------------------------------------- /2025-2026/10a/utils/bst.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "bst.h" 4 | 5 | Node* init_node(int val) { 6 | Node* node = (Node*)malloc(sizeof(Node)); 7 | node->val = val; 8 | node->left = NULL; 9 | node->right = NULL; 10 | 11 | return node; 12 | } 13 | 14 | void inorder(Node* root) { 15 | if (root == NULL) { 16 | return; 17 | } 18 | 19 | inorder(root->left); 20 | printf("%d ", root->val); 21 | inorder(root->right); 22 | } 23 | 24 | Node* bst_insert(Node* root, int val) { 25 | if (root == NULL) { 26 | return init_node(val); 27 | } 28 | 29 | if (root->val > val) { 30 | root->left = bst_insert(root->left, val); 31 | } else { 32 | root->right = bst_insert(root->right, val); 33 | } 34 | 35 | return root; 36 | } 37 | -------------------------------------------------------------------------------- /2024-2025/10v/2024_10_11 DoublyLinkedLists/dLinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | 4 | struct Node { 5 | struct Node* next; 6 | struct Node* prev; 7 | int val; 8 | }; 9 | 10 | typedef struct Node Node; 11 | 12 | typedef struct Dlist { 13 | struct Node* head; 14 | struct Node* tail; 15 | int size; 16 | } Dlist; 17 | 18 | Dlist initList(); 19 | 20 | Node* createNode(int val); 21 | 22 | void pushFront(Dlist* list, int val); 23 | void pushBack(Dlist* list, int val); 24 | void pushAt(Dlist* list, int val, int idx); 25 | 26 | void popFront(Dlist* list); 27 | void popBack(Dlist* list); 28 | void popAt(Dlist* list, int idx); 29 | 30 | Node* getAt(Dlist* list, int idx); 31 | 32 | void printFromHead(Dlist* list); 33 | void printFromTail(Dlist* list); 34 | 35 | void release(Dlist* list); 36 | 37 | #endif -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-04-Insertion_sort_and_lists/dlist_preview.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dlist.h" 3 | 4 | int main() 5 | { 6 | DList *l = init_dlist(); 7 | printDList(l); // EMPTY 8 | insertBegin(l, 1); 9 | printDList(l); // 1 10 | popFront(l); 11 | printDList(l); // EMPTY 12 | insertEnd(l, 5); 13 | printDListReverse(l); // 5 14 | 15 | insertBegin(l, 2); 16 | insertBegin(l, 3); 17 | insertBegin(l, 4); 18 | printDList(l); // 4 3 2 5 19 | 20 | int val = popFront(l); 21 | printf("popped = %d\n", val); // popped = 4 22 | printDList(l); // 3 2 5 23 | 24 | val = pop(l); 25 | printf("popped = %d\n", val); // popped = 5 26 | printDListReverse(l); // 2 3 27 | 28 | printf("at 3 = %d ", getAt(l, 1)); // 2 29 | 30 | clear(l); 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-10-Exercise_2/dlist.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | 4 | typedef struct Node 5 | { 6 | int value; 7 | struct Node *next; 8 | struct Node *prev; 9 | } Node; 10 | typedef struct DList 11 | { 12 | Node *head; 13 | Node *tail; 14 | } DList; 15 | 16 | DList *init_dlist(); 17 | void insertBegin(DList *, int); 18 | void insertEnd(DList *, int); 19 | 20 | Node *getAt(DList *, int); 21 | void clear(DList *); 22 | int pop(DList *); 23 | void printDList(DList *); 24 | void printDListReverse(DList *); 25 | int popFront(DList *); 26 | 27 | void insertAt(DList *, Node *, Node *); 28 | Node *removeAt(DList *, Node *); 29 | 30 | Node *createNode(int val); 31 | void insertBefore(DList *l, Node *it, Node *val); 32 | void insertAfter(DList *l, Node *it, Node *val); 33 | Node *removeAt(DList *l, Node *val); 34 | #endif 35 | -------------------------------------------------------------------------------- /2023-2024/10a/utils/dlist.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | 4 | typedef struct Node 5 | { 6 | void *value; 7 | struct Node *next; 8 | struct Node *prev; 9 | } Node; 10 | typedef struct DList 11 | { 12 | Node *head; 13 | Node *tail; 14 | } DList; 15 | 16 | DList *init_dlist(); 17 | void insertBegin(DList *, void *); 18 | void insertEnd(DList *, void *); 19 | 20 | Node *getAt(DList *, void *); 21 | void clear(DList *); 22 | void *pop(DList *); 23 | void printDList(DList *); 24 | void printDListReverse(DList *); 25 | void *popFront(DList *); 26 | 27 | void insertAt(DList *, Node *, Node *); 28 | Node *removeAt(DList *, Node *); 29 | 30 | Node *createNode(void *val); 31 | void insertBefore(DList *l, Node *it, Node *val); 32 | void insertAfter(DList *l, Node *it, Node *val); 33 | Node *removeAt(DList *l, Node *val); 34 | #endif 35 | -------------------------------------------------------------------------------- /2023-2024/10a/2024-03-26-leet-code-graphs/keys_and_rooms.c: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/keys-and-rooms/description/ 2 | 3 | void visitRoom(int **rooms, int *visited, int current, int *roomsColSize) 4 | { 5 | if (visited[current]) 6 | { 7 | return; 8 | } 9 | 10 | visited[current] = 1; 11 | 12 | for (int i = 0; i < roomsColSize[current]; i++) 13 | { 14 | visitRoom(rooms, visited, rooms[current][i], roomsColSize); 15 | } 16 | } 17 | 18 | bool canVisitAllRooms(int **rooms, int roomsSize, int *roomsColSize) 19 | { 20 | int *visited = (int *)calloc(roomsSize, sizeof(int)); 21 | visitRoom(rooms, visited, 0, roomsColSize); 22 | 23 | for (int i = 0; i < roomsSize; i++) 24 | { 25 | if (visited[i] == 0) 26 | { 27 | return false; 28 | } 29 | } 30 | 31 | return true; 32 | } -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-15-stack/insertionSort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../utils/vector.h" 3 | 4 | int main() { 5 | vector* v = init_vector(); 6 | 7 | push(v, 5); 8 | push(v, 50); 9 | push(v, 23); 10 | push(v, 18); 11 | push(v, 30); 12 | push(v, 27); 13 | push(v, 100); 14 | push(v, 0); 15 | 16 | //insertion sort 17 | /* 18 | Number of operations 19 | 1 + (n-1)*(5) + n*(n+1) 20 | = 1 + 5n - 5 + n^2 + n 21 | = n^2 + 6n - 4 22 | */ 23 | for (int i = 1; i < v->size; i++) { 24 | int temp = v->data[i]; 25 | int j = i - 1; 26 | for (; j >= 0; j--) { 27 | if (v->data[j] < temp) { 28 | break; 29 | } 30 | v->data[j+1] = v->data[j]; 31 | } 32 | 33 | v->data[j+1] = temp; 34 | } 35 | 36 | print_vector(v); 37 | 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-10-05-quicksort-exercise/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int *a, int *b) { 4 | int c = *a; 5 | *a = *b; 6 | *b = c; 7 | } 8 | 9 | void quick_sort(int *arr, unsigned int size) { 10 | // recursion condition 11 | // choose pivot 12 | int pivot_index = size/2; // int is rounded down 13 | 14 | // rearrange around pivot 15 | for(int i = 0; i < pivot_index; i++) { 16 | if(arr[i] > arr[pivot_index]) { 17 | // move to the right 18 | swap(arr + i, arr + pivot_index - 1); 19 | swap(arr + pivot_index-1, arr+pivot_index); 20 | pivot_index--; 21 | i--; 22 | } 23 | } 24 | 25 | // call recursively for left half and right half 26 | } 27 | 28 | int main() { 29 | int arr[] = {9, 3, 2, 7, 5, 1, 4, 8, 0, 6}; 30 | 31 | //quick_sort(arr, 10); 32 | 33 | for(int i = 0; i < 10; i++) 34 | printf("[%d] %d\n", i, arr[i]); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /2024-2025/10b/2024-10-07-quick-sort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void quick_sort(int numbers[], unsigned int count) { 4 | int anchor = 0; 5 | 6 | for(int i = anchor + 1; i < count; i++) { 7 | if(numbers[i] < numbers[anchor]) { 8 | // a b c A x d z 9 | int tmp = numbers[i]; // tmp == d 10 | for(int j = i - 1; j >= anchor; j--) 11 | numbers[j + 1] = numbers[j]; 12 | // a b c A A x z 13 | numbers[anchor] = tmp; // A => d 14 | // a b c d A x z 15 | anchor++; 16 | } 17 | } 18 | } 19 | 20 | int main() { 21 | int numbers[8] = {6, 8, 3, 7, 2, 4, 5, 1}; 22 | 23 | for(int i = 0; i < 8; i++) 24 | printf("numbers[%d] = %d\n", i, numbers[i]); 25 | 26 | quick_sort(numbers, 8); 27 | 28 | puts(""); 29 | for(int i =0; i < 8; i++) 30 | printf("numbers[%d] = %d\n", i, numbers[i]); 31 | 32 | return 0; 33 | } -------------------------------------------------------------------------------- /2024-2025/10a/2024-10-14-stack/stack.c: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | #include 3 | #include 4 | 5 | Node* init_node(int val) { 6 | Node* node = (Node*)malloc(sizeof(Node)); 7 | node->next = NULL; 8 | node->val = val; 9 | 10 | return node; 11 | }; 12 | 13 | Stack* init_stack() { 14 | Stack* l = (Stack*)malloc(sizeof(Stack)); 15 | 16 | l->top = NULL; 17 | 18 | return l; 19 | }; 20 | 21 | void push(Stack* l, int val) { 22 | Node* newNode = init_node(val); 23 | 24 | newNode->next = l->top; 25 | l->top = newNode; 26 | }; 27 | 28 | int isEmpty(Stack *l) { 29 | return l->top == NULL; 30 | } 31 | 32 | int pop(Stack* l) { 33 | if (isEmpty(l)) { 34 | printf("Cannot pop from empty list"); 35 | exit(1); 36 | } 37 | 38 | int val = l->top->val; 39 | Node* tmp = l->top; 40 | l->top = l->top->next; 41 | 42 | free(tmp); 43 | 44 | return val; 45 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-02-26-graph-2/graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "list.h" 4 | 5 | struct graph_node_t { 6 | char* name; 7 | list_t* edges; 8 | }; 9 | 10 | struct graph_t { 11 | int size; 12 | list_t* nodes; 13 | }; 14 | 15 | typedef struct graph_node_t graph_node_t; 16 | typedef struct graph_t graph_t; 17 | 18 | graph_node_t* init_graph_node(char* name); 19 | graph_t* init_graph(); 20 | 21 | void connect_nodes(graph_node_t* node1, graph_node_t* node2); 22 | 23 | graph_node_t* find_node_by_name(graph_t* graph, char* name); 24 | 25 | graph_node_t* add_graph_node(graph_t* graph, char* name); 26 | 27 | void print_graph(graph_t* graph); 28 | 29 | graph_t* init_graph_from_strings(char* lines[]); 30 | 31 | 32 | struct tree_t { 33 | struct list_t* children; 34 | void* value; 35 | }; 36 | 37 | typedef struct tree_t tree_t; 38 | 39 | tree_t* graph_span_tree(graph_t* graph, char* name); -------------------------------------------------------------------------------- /2022-2023/10b/2023-06-02-encryption-1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | unsigned char* add_int(unsigned char* str, int a) { 6 | unsigned char* out = malloc(strlen(str) + 1); 7 | 8 | for(int i = 0; i < strlen(str); i++) { 9 | out[i] = (str[i] + a) % 256; 10 | } 11 | 12 | out[strlen(str) + 1] = '\0'; 13 | return out; 14 | } 15 | 16 | 17 | 18 | unsigned char* table_method(unsigned char* str, int a) { 19 | unsigned char* out = malloc(strlen(str) + 1); 20 | 21 | for(int i = 0; i < strlen(str); i++) { 22 | out[i] = str[i + (i*a)]; 23 | } 24 | 25 | out[strlen(str) + 1] = '\0'; 26 | return out; 27 | } 28 | 29 | int main() { 30 | unsigned char* str = "hello 10b"; 31 | 32 | unsigned char* out_1 = add_int(str, 3); 33 | 34 | printf("\"%s\"\n", str); 35 | printf("\"%s\"\n", out_1); 36 | 37 | return 0; 38 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-03-06-a-star/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vector.h" 4 | 5 | void swap(void* a, void* b) { 6 | void* c = a; 7 | a = b; 8 | b = c; 9 | } 10 | 11 | struct vector_t* vector_init() { 12 | struct vector_t* new_vec = malloc(sizeof(struct vector_t)); 13 | 14 | new_vec->size = 0; 15 | new_vec->values = NULL; 16 | 17 | return new_vec; 18 | } 19 | 20 | void vector_add(struct vector_t* vec, void* value) { 21 | vec->values = realloc(vec->values, (vec->size + 1) * sizeof(void*)); 22 | vec->values[vec->size] = value; 23 | vec->size++; 24 | } 25 | 26 | void* vector_get(struct vector_t* vec, int index) { 27 | if(index > vec->size) return NULL; 28 | return vec->values[index]; 29 | } 30 | 31 | void vector_reverse(struct vector_t* vec) { 32 | if(vec->size == 0) return; 33 | 34 | for(int i = 0; i < vec->size / 2; i++) { 35 | swap( 36 | vec->values + i, 37 | vec->values + vec->size - 1 - i 38 | ); 39 | } 40 | } -------------------------------------------------------------------------------- /2024-2025/10v/2024_11_13 set and treeSet/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "./Set/set.h" 3 | #include "./TreeSet/treeSet.h" 4 | 5 | 6 | int main() { 7 | // Set* mySet = initSet(); 8 | TreeNode* myTreeSet = initTreeNode(5); 9 | 10 | treeSetAdd(myTreeSet, 5); 11 | treeSetAdd(myTreeSet, 3); 12 | treeSetAdd(myTreeSet, 4); 13 | treeSetAdd(myTreeSet, 1); 14 | treeSetAdd(myTreeSet, 1); 15 | printf("%d\n", treeSetHeight(myTreeSet)); 16 | treeSetAdd(myTreeSet, 0); 17 | printf("%d\n", treeSetHeight(myTreeSet)); 18 | // // OR 19 | // treeSetAdd2(&myTreeSet, 5); 20 | // treeSetAdd2(&myTreeSet, 3); 21 | // treeSetAdd2(&myTreeSet, 4); 22 | // treeSetAdd2(&myTreeSet, 1); 23 | // treeSetAdd2(&myTreeSet, 1); 24 | // printTreeSet(myTreeSet); 25 | // setAdd(mySet, 5); 26 | // setAdd(mySet, 3); 27 | // setAdd(mySet, 4); 28 | // setAdd(mySet, 1); 29 | // setAdd(mySet, 1); 30 | // printSet(mySet); 31 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-24-dijkstra-route/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "vector.h" 4 | 5 | void swap(void* a, void* b) { 6 | void* c = a; 7 | a = b; 8 | b = c; 9 | } 10 | 11 | struct vector_t* vector_init() { 12 | struct vector_t* new_vec = malloc(sizeof(struct vector_t)); 13 | 14 | new_vec->size = 0; 15 | new_vec->values = NULL; 16 | 17 | return new_vec; 18 | } 19 | 20 | void vector_add(struct vector_t* vec, void* value) { 21 | vec->values = realloc(vec->values, (vec->size + 1) * sizeof(void*)); 22 | vec->values[vec->size] = value; 23 | vec->size++; 24 | } 25 | 26 | void* vector_get(struct vector_t* vec, int index) { 27 | if(index > vec->size) return NULL; 28 | return vec->values[index]; 29 | } 30 | 31 | void vector_reverse(struct vector_t* vec) { 32 | if(vec->size == 0) return; 33 | 34 | for(int i = 0; i < vec->size / 2; i++) { 35 | swap( 36 | vec->values + i, 37 | vec->values + vec->size - 1 - i 38 | ); 39 | } 40 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-02-26-graph-2/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = NULL; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | void push_list(list_t* list, void* value) { 15 | if(list->next == NULL) { 16 | list->next = init_list(); 17 | list->next->value = value; 18 | } else { 19 | push_list(list->next, value); 20 | } 21 | } 22 | 23 | void* list_get_at( 24 | list_t* list, 25 | unsigned int index 26 | ) { 27 | list_t* curr = list; 28 | int i = 0; 29 | 30 | while(inext; 32 | i++; 33 | } 34 | 35 | return curr->value; 36 | } 37 | 38 | int list_length(list_t* list) { 39 | int count = 0; 40 | while(list != NULL) { 41 | count++; 42 | list = list->next; 43 | } 44 | 45 | return count; 46 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-06-09-des-1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Initial permutation for the data 4 | uint8_t IP_TABLE[64] = { 5 | 6, 2, 7, 0, 3, 4, 1, 5 6 | // 58, 50, 42, 34, 26, 18, 10, 2, 7 | // 60, 52, 44, 36, 28, 20, 12, 4, 8 | // 62, 54, 46, 38, 30, 22, 14, 6, 9 | // 64, 56, 48, 40, 32, 24, 16, 8, 10 | // 57, 49, 41, 33, 25, 17, 9, 1, 11 | // 59, 51, 43, 35, 27, 19, 11, 3, 12 | // 61, 53, 45, 37, 29, 21, 13, 5, 13 | // 63, 55, 47, 39, 31, 23, 15, 7 14 | }; 15 | 16 | uint8_t* encrypt( 17 | uint8_t* data, // 64 bits 18 | uint8_t* key // 56 bits 19 | ) { 20 | // I = IP(data) 21 | // L0, R0 = split(I) 22 | // ... 23 | // R = join(L0, R0) 24 | // O = FP(R) 25 | 26 | uint8_t d = data[0]; 27 | uint8_t r = 0; 28 | 29 | for(int i = 0; i < 8; i++) { 30 | // r[i] = d[IP_TABLE[i]]; 31 | r << 1; 32 | r |= (d >> (7 - IP_TABLE[i])) & 1; 33 | } 34 | } 35 | 36 | 37 | int main() { 38 | return 0; 39 | } -------------------------------------------------------------------------------- /2023-2024/10b/2023-11-20-bst-2/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "queue.h" 4 | 5 | queue_t* init_queue() { 6 | queue_t* q = (queue_t*)malloc(sizeof(queue_t)); 7 | 8 | q->head = q->tail = NULL; 9 | 10 | return q; 11 | } 12 | 13 | int queue_empty(queue_t* q) { 14 | return q->head == NULL; 15 | } 16 | 17 | void queue_push(queue_t* q, void* value) { 18 | struct q_node_t* new_node = malloc(sizeof(struct q_node_t)); 19 | new_node->next = NULL; 20 | new_node->value = value; 21 | 22 | if(q->tail != NULL) { 23 | q->tail->next = new_node; 24 | q->tail = new_node; 25 | } else { 26 | q->head = q->tail = new_node; 27 | } 28 | } 29 | 30 | void* queue_pop(queue_t* q) { 31 | void* value = q->head->value; 32 | struct q_node_t* old_head = q->head; 33 | 34 | q->head = q->head->next; 35 | if(q->head == NULL) 36 | q->tail = NULL; 37 | 38 | free(old_head); 39 | // old_head = NULL; 40 | 41 | return value; 42 | } -------------------------------------------------------------------------------- /2023-2024/10b/2023-11-27-bst-3/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "queue.h" 4 | 5 | queue_t* init_queue() { 6 | queue_t* q = (queue_t*)malloc(sizeof(queue_t)); 7 | 8 | q->head = q->tail = NULL; 9 | 10 | return q; 11 | } 12 | 13 | int queue_empty(queue_t* q) { 14 | return q->head == NULL; 15 | } 16 | 17 | void queue_push(queue_t* q, void* value) { 18 | struct q_node_t* new_node = malloc(sizeof(struct q_node_t)); 19 | new_node->next = NULL; 20 | new_node->value = value; 21 | 22 | if(q->tail != NULL) { 23 | q->tail->next = new_node; 24 | q->tail = new_node; 25 | } else { 26 | q->head = q->tail = new_node; 27 | } 28 | } 29 | 30 | void* queue_pop(queue_t* q) { 31 | void* value = q->head->value; 32 | struct q_node_t* old_head = q->head; 33 | 34 | q->head = q->head->next; 35 | if(q->head == NULL) 36 | q->tail = NULL; 37 | 38 | free(old_head); 39 | // old_head = NULL; 40 | 41 | return value; 42 | } -------------------------------------------------------------------------------- /2023-2024/10b/2023-12-11-bst-4/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "queue.h" 4 | 5 | queue_t* init_queue() { 6 | queue_t* q = (queue_t*)malloc(sizeof(queue_t)); 7 | 8 | q->head = q->tail = NULL; 9 | 10 | return q; 11 | } 12 | 13 | int queue_empty(queue_t* q) { 14 | return q->head == NULL; 15 | } 16 | 17 | void queue_push(queue_t* q, void* value) { 18 | struct q_node_t* new_node = malloc(sizeof(struct q_node_t)); 19 | new_node->next = NULL; 20 | new_node->value = value; 21 | 22 | if(q->tail != NULL) { 23 | q->tail->next = new_node; 24 | q->tail = new_node; 25 | } else { 26 | q->head = q->tail = new_node; 27 | } 28 | } 29 | 30 | void* queue_pop(queue_t* q) { 31 | void* value = q->head->value; 32 | struct q_node_t* old_head = q->head; 33 | 34 | q->head = q->head->next; 35 | if(q->head == NULL) 36 | q->tail = NULL; 37 | 38 | free(old_head); 39 | // old_head = NULL; 40 | 41 | return value; 42 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-11-graph-3/graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "list.h" 4 | 5 | typedef struct graph_edge_t graph_edge_t; 6 | typedef struct graph_node_t graph_node_t; 7 | typedef struct graph_t graph_t; 8 | 9 | struct graph_edge_t { 10 | int weight; 11 | graph_node_t* l_node; 12 | graph_node_t* r_node; 13 | }; 14 | 15 | struct graph_node_t { 16 | char* name; 17 | list_t* edges; // graph_edge_t* 18 | }; 19 | 20 | struct graph_t { 21 | int size; 22 | list_t* nodes; // graph_t* 23 | }; 24 | 25 | graph_edge_t* init_graph_edge(int weight); 26 | graph_node_t* init_graph_node(char* name); 27 | graph_t* init_graph(); 28 | 29 | void destroy_graph_edge(graph_edge_t*); 30 | void destroy_graph_node(graph_node_t*); 31 | void destroy_graph(graph_t*); 32 | 33 | 34 | graph_node_t* find_node_by_name(graph_t* graph, char* name); 35 | void print_graph(graph_t* graph); 36 | 37 | graph_node_t* add_graph_node(graph_t* graph, char* name); 38 | void connect_nodes(graph_node_t* node1, graph_node_t* node2, int weight); 39 | -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-18-dijkstra-2/graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "list.h" 4 | 5 | typedef struct graph_edge_t graph_edge_t; 6 | typedef struct graph_node_t graph_node_t; 7 | typedef struct graph_t graph_t; 8 | 9 | struct graph_edge_t { 10 | int weight; 11 | graph_node_t* l_node; 12 | graph_node_t* r_node; 13 | }; 14 | 15 | struct graph_node_t { 16 | char* name; 17 | list_t* edges; // graph_edge_t* 18 | }; 19 | 20 | struct graph_t { 21 | int size; 22 | list_t* nodes; // graph_t* 23 | }; 24 | 25 | graph_edge_t* init_graph_edge(int weight); 26 | graph_node_t* init_graph_node(char* name); 27 | graph_t* init_graph(); 28 | 29 | void destroy_graph_edge(graph_edge_t*); 30 | void destroy_graph_node(graph_node_t*); 31 | void destroy_graph(graph_t*); 32 | 33 | 34 | graph_node_t* find_node_by_name(graph_t* graph, char* name); 35 | void print_graph(graph_t* graph); 36 | 37 | graph_node_t* add_graph_node(graph_t* graph, char* name); 38 | void connect_nodes(graph_node_t* node1, graph_node_t* node2, int weight); 39 | -------------------------------------------------------------------------------- /2024-2025/10a/2024-09-26-vector/main.c: -------------------------------------------------------------------------------- 1 | #include "vector.h" 2 | #include 3 | 4 | int main() { 5 | vector* v = init_vector(2); 6 | 7 | push(v, 10); 8 | push(v, 3); 9 | printf("cap: %d\n", v->capacity); 10 | 11 | push(v, 5); 12 | push(v, 6); 13 | push(v, -5); 14 | 15 | printf("cap: %d\n", v->capacity); 16 | print_vector(v); 17 | 18 | // Bubble sort 19 | // [-5, 3, 4, 5, 10] 20 | 21 | int iterations = 0; 22 | for (int j = 0; j < v->size; j++) { 23 | int hasSwapped = 0; 24 | iterations++; 25 | 26 | for (int i = 0; i < v->size - 1 - j; i++) { 27 | if (v->arr[i] > v->arr[i + 1]) { 28 | int tmp = v->arr[i]; 29 | v->arr[i] = v->arr[i + 1]; 30 | v->arr[i + 1] = tmp; 31 | 32 | hasSwapped = 1; 33 | } 34 | } 35 | 36 | if (!hasSwapped) { 37 | break; 38 | } 39 | } 40 | 41 | printf("iterations %d\n", iterations); 42 | print_vector(v); 43 | 44 | free_vector(v); 45 | } -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-22-binary-search/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../utils/vector.h" 4 | 5 | bool binary_search(vector* v, int val) { 6 | int left = 0; 7 | int right = v->size - 1; 8 | 9 | while (left <= right) { 10 | int mid = (left + right) / 2; 11 | printf("mid - %d, val - %d\n", mid, v->data[mid]); 12 | if (v->data[mid] == val) { 13 | return true; 14 | } else if (v->data[mid] > val) { 15 | right = mid - 1; 16 | } else { 17 | left = mid + 1; 18 | } 19 | } 20 | 21 | return false; 22 | } 23 | 24 | 25 | int main() { 26 | vector* v = init_vector(); 27 | push(v, 10); 28 | push(v, 20); 29 | push(v, 30); 30 | push(v, 40); 31 | push(v, 50); 32 | push(v, 60); 33 | push(v, 70); 34 | push(v, 80); 35 | push(v, 90); 36 | 37 | print_vector(v); 38 | if (binary_search(v, 15)) { 39 | printf("found\n"); 40 | } else { 41 | printf("not found\n"); 42 | } 43 | 44 | return 1; 45 | } -------------------------------------------------------------------------------- /2024-2025/10v/2024_11_22 bfs/dLinkedList_TreeNode.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | 4 | struct TreeNode { 5 | struct TreeNode* left; 6 | struct TreeNode* right; 7 | int val; 8 | }; 9 | 10 | typedef struct TreeNode TreeNode; 11 | 12 | typedef TreeNode* DataType; 13 | 14 | struct ListNode { 15 | struct ListNode* next; 16 | struct ListNode* prev; 17 | DataType val; 18 | }; 19 | 20 | typedef struct ListNode ListNode; 21 | 22 | typedef struct Dlist { 23 | struct ListNode* head; 24 | struct ListNode* tail; 25 | int size; 26 | } Dlist; 27 | 28 | Dlist initList(); 29 | 30 | ListNode* createListNode(DataType val); 31 | 32 | void pushFront(Dlist* list, DataType val); 33 | void pushBack(Dlist* list, DataType val); 34 | void pushAt(Dlist* list, DataType val, int idx); 35 | 36 | void popFront(Dlist* list); 37 | void popBack(Dlist* list); 38 | void popAt(Dlist* list, int idx); 39 | 40 | ListNode* getAt(Dlist* list, int idx); 41 | 42 | void printFromHead(Dlist* list); 43 | void printFromTail(Dlist* list); 44 | 45 | void release(Dlist* list); 46 | 47 | #endif -------------------------------------------------------------------------------- /2022-2023/10b/2022-09-19-revision/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int foo(); 4 | 5 | int main() { 6 | printf("Hello\n"); 7 | 8 | int a = 5; 9 | int b; 10 | 11 | printf("%d %d\n", a, b); 12 | 13 | // int float double char 14 | // unsigned int 15 | // long int / long 16 | // short int / short 17 | // unsigned long 18 | 19 | int arr[3]; 20 | int arr2[5] = {1, 2, 3}; 21 | 22 | int *p = &a; 23 | printf( 24 | "[%p] %p => [%p] %d\n *p=%d\n", 25 | &p, p, &a, a, 26 | *p 27 | ); 28 | 29 | printf("%d %d\n", arr[0], *(arr + 0)); 30 | 31 | int *arr3 = arr; 32 | 33 | printf("%d %d\n", arr3[0], *(arr3 + 0)); 34 | 35 | for(int i = 0; i < 3; i++) { 36 | printf("%d\n", arr[i]); 37 | // printf("%d\n", *(arr + i)); 38 | } 39 | 40 | int c = 5; 41 | int d = c == 5 ? 1 : 0; 42 | // c == 5 ? print_hello() : print_goodbye(); 43 | 44 | foo(); 45 | 46 | return 0; 47 | } 48 | 49 | int foo() { 50 | printf("foo"); 51 | return 1; 52 | } 53 | 54 | void bar(int a, int *b) { 55 | a = 10; 56 | *b = 10; 57 | } 58 | 59 | int a = 5; 60 | bar(a, &a) -------------------------------------------------------------------------------- /2022-2023/10b/2023-03-06-a-star/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "queue.h" 4 | 5 | struct queue_t* init_queue() { 6 | struct queue_t* new_q = malloc(sizeof(struct queue_t)); 7 | 8 | new_q->head = NULL; 9 | new_q->tail = NULL; 10 | 11 | return new_q; 12 | } 13 | 14 | void queue_add(struct queue_t* q, void* value, int priority) { 15 | struct queue_node_t* new_node = malloc(sizeof(struct queue_node_t)); 16 | new_node->next = NULL; 17 | new_node->value = value; 18 | 19 | if(q->head == NULL) { 20 | q->head = q->tail = new_node; 21 | } else { 22 | struct queue_node_t* curr = q->head; 23 | for(; curr->priority < priority && curr != q->tail; curr = curr->next); 24 | 25 | curr->next = new_node; 26 | if(curr == q->tail) 27 | q->tail = new_node; 28 | } 29 | } 30 | 31 | void* queue_remove(struct queue_t* q) { 32 | if(q->head == NULL) return NULL; 33 | 34 | void* val = q->head->value; 35 | free(q->head); 36 | q->head = q->head->next; 37 | 38 | return val; 39 | } 40 | -------------------------------------------------------------------------------- /2022-2023/10b/2023-02-24-dijkstra-route/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "queue.h" 4 | 5 | struct queue_t* init_queue() { 6 | struct queue_t* new_q = malloc(sizeof(struct queue_t)); 7 | 8 | new_q->head = NULL; 9 | new_q->tail = NULL; 10 | 11 | return new_q; 12 | } 13 | 14 | void queue_add(struct queue_t* q, void* value, int priority) { 15 | struct queue_node_t* new_node = malloc(sizeof(struct queue_node_t)); 16 | new_node->next = NULL; 17 | new_node->value = value; 18 | 19 | if(q->head == NULL) { 20 | q->head = q->tail = new_node; 21 | } else { 22 | struct queue_node_t* curr = q->head; 23 | for(; curr->priority < priority && curr != q->tail; curr = curr->next); 24 | 25 | curr->next = new_node; 26 | if(curr == q->tail) 27 | q->tail = new_node; 28 | } 29 | } 30 | 31 | void* queue_remove(struct queue_t* q) { 32 | if(q->head == NULL) return NULL; 33 | 34 | void* val = q->head->value; 35 | free(q->head); 36 | q->head = q->head->next; 37 | 38 | return val; 39 | } 40 | -------------------------------------------------------------------------------- /2023-2024/10b/2023-10-02-intro-3/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = 0; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | void push_list(list_t* list, int value) { 15 | // list_t* new_node = init_list(); 16 | // new_node->value = value; 17 | 18 | // // list_t* tmp = list; 19 | // while(list->next != NULL) 20 | // list = list->next; 21 | 22 | // list->next = new_node; 23 | 24 | if(list->next == NULL) { 25 | list->next = init_list(); 26 | list->next->value = value; 27 | } else { 28 | push_list(list->next, value); 29 | } 30 | } 31 | 32 | int list_get_at( 33 | list_t* vec, 34 | unsigned int index 35 | // int* err 36 | ) { 37 | // if(vec->count <= index) { 38 | // // return -1; 39 | // // *err = 1; 40 | // return 0; 41 | // } 42 | 43 | // // *err = 0; 44 | // return vec->arr[index]; 45 | return -1; 46 | } -------------------------------------------------------------------------------- /2023-2024/10b/2023-10-06-intro-4/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = 0; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | void push_list(list_t* list, int value) { 15 | // list_t* new_node = init_list(); 16 | // new_node->value = value; 17 | 18 | // // list_t* tmp = list; 19 | // while(list->next != NULL) 20 | // list = list->next; 21 | 22 | // list->next = new_node; 23 | 24 | if(list->next == NULL) { 25 | list->next = init_list(); 26 | list->next->value = value; 27 | } else { 28 | push_list(list->next, value); 29 | } 30 | } 31 | 32 | int list_get_at( 33 | list_t* vec, 34 | unsigned int index 35 | // int* err 36 | ) { 37 | // if(vec->count <= index) { 38 | // // return -1; 39 | // // *err = 1; 40 | // return 0; 41 | // } 42 | 43 | // // *err = 0; 44 | // return vec->arr[index]; 45 | return -1; 46 | } -------------------------------------------------------------------------------- /2024-2025/10a/utils/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | 6 | Stack *init_stack() 7 | { 8 | Stack *stack = (Stack *)malloc(sizeof(Stack)); 9 | stack->top = NULL; 10 | } 11 | 12 | void push(Stack *stack, int val) 13 | { 14 | StackNode *node = create_node(val); 15 | node->next = stack->top; 16 | stack->top = node; 17 | } 18 | 19 | int pop(Stack *stack) 20 | { 21 | if (stack->top == NULL) 22 | { 23 | printf("Stack is empty.\n"); 24 | exit(1); 25 | } 26 | 27 | int val = stack->top->val; 28 | StackNode *tmp = stack->top; 29 | stack->top = stack->top->next; 30 | free(tmp); 31 | 32 | return val; 33 | } 34 | 35 | void clear_stack(Stack *stack) 36 | { 37 | while (stack->top != NULL) 38 | { 39 | pop(stack); 40 | } 41 | 42 | free(stack); 43 | } 44 | 45 | void print_stack(Stack *stack) 46 | { 47 | StackNode *it = stack->top; 48 | printf("S: "); 49 | while (it != NULL) 50 | { 51 | printf("%d -> ", it->val); 52 | it = it->next; 53 | } 54 | printf("NULL\n"); 55 | } -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-15-stack/merge.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../utils/vector.h" 3 | 4 | vector* merge(vector* v1, vector* v2) { 5 | int i = 0; 6 | int j = 0; 7 | vector* res = init_vector(); 8 | 9 | while (i < v1->size && j < v2->size) { 10 | if (v1->data[i] < v2->data[j]) { 11 | push(res, v1->data[i]); 12 | i++; 13 | } else { 14 | push(res, v2->data[j]); 15 | j++; 16 | } 17 | } 18 | 19 | while (i < v1->size) { 20 | push(res, v1->data[i]); 21 | i++; 22 | } 23 | 24 | while (j < v2->size) { 25 | push(res, v2->data[j]); 26 | j++; 27 | } 28 | 29 | return res; 30 | } 31 | 32 | int main() { 33 | vector* v1 = init_vector(); 34 | vector* v2 = init_vector(); 35 | 36 | push(v1, 10); 37 | push(v1, 20); 38 | push(v1, 25); 39 | push(v1, 30); 40 | push(v1, 31); 41 | 42 | push(v2, 5); 43 | push(v2, 6); 44 | push(v2, 17); 45 | push(v2, 28); 46 | 47 | vector* res = merge(v1, v2); 48 | print_vector(res); 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /2024-2025/10a/2024-10-14-stack/main.c: -------------------------------------------------------------------------------- 1 | #include "stack.h" 2 | #include 3 | int main() { 4 | // read str from stdin 5 | // print reverse 6 | 7 | // Stack* st = init_stack(); 8 | // char c; 9 | // do { 10 | // scanf("%c", &c); 11 | // push(st, (int)c); 12 | // } while (c != '\n'); 13 | 14 | // while (! isEmpty(st)) { 15 | // printf("%c", (char)pop(st)); 16 | // } 17 | 18 | // given a string '()()()(())' 19 | // check if brackets are balanced 20 | // '(()' ')' 21 | // ')(' 22 | // use stack 23 | Stack* st = init_stack(); 24 | char c; 25 | 26 | do { 27 | scanf("%c", &c); 28 | 29 | if (c == '(') { 30 | push(st, (int)c); 31 | } else if (c == ')') { 32 | if (isEmpty(st)) { 33 | printf("not balanced"); 34 | return 0; 35 | } 36 | 37 | pop(st); 38 | } 39 | 40 | } while (c != '\n'); 41 | 42 | if (isEmpty(st)) { 43 | printf("balanced"); 44 | } else { 45 | printf("not balanced"); 46 | } 47 | 48 | 49 | return 0; 50 | } -------------------------------------------------------------------------------- /2024-2025/10v/2024_11_13 set and treeSet/Set/set.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "set.h" 4 | 5 | #define INITAL_CAPACITY 16 6 | 7 | Set* initSet() { 8 | Set* newSet = (Set*)malloc(sizeof(Set)); 9 | newSet->size = 0; 10 | newSet->capacity = INITAL_CAPACITY; 11 | newSet->data = (int*)malloc(sizeof(int) * INITAL_CAPACITY); 12 | return newSet; 13 | } 14 | 15 | int setContains(Set* set, int val) { 16 | for(int i = 0; i < set->size; i++) { 17 | if(set->data[i] == val) { 18 | return 1; 19 | } 20 | } 21 | return 0; 22 | } 23 | 24 | void setAdd(Set* set, int val) { 25 | if(setContains(set, val)) { 26 | return; 27 | } 28 | if(set->size >= set->capacity) { 29 | set->capacity*=2; 30 | set->data = realloc(set->data, sizeof(int) * set->capacity); 31 | if(!set->data) { 32 | exit(1); 33 | } 34 | } 35 | set->data[set->size] = val; 36 | set->size++; 37 | } 38 | 39 | void printSet(Set* set) { 40 | for(int i = 0; i < set->size; i++) { 41 | printf("%d ", set->data[i]); 42 | } 43 | printf("\n"); 44 | } -------------------------------------------------------------------------------- /2024-2025/10a/utils/tree.c: -------------------------------------------------------------------------------- 1 | #include "tree.h" 2 | #include 3 | #include 4 | 5 | //Binary Search Tree 6 | Node* create_node(int val) { 7 | Node* node = (Node*)malloc(sizeof(Node)); 8 | node->left = NULL; 9 | node->right = NULL; 10 | node->val = val; 11 | 12 | return node; 13 | } 14 | 15 | // O(h) 16 | Node* bst_insert(Node* root, int v) { 17 | if (root == NULL) { 18 | return create_node(v); 19 | } 20 | 21 | if (root->val >= v) { 22 | root->left = bst_insert(root->left, v); 23 | } 24 | else { 25 | root->right = bst_insert(root->right, v); 26 | } 27 | 28 | return root; 29 | } 30 | 31 | 32 | // O(n) 33 | void printTree(Node* root) { 34 | if (root == NULL) { 35 | return; 36 | } 37 | 38 | //preorder 39 | // printf("%d ", root->val); 40 | // printTree(root->left); 41 | // printTree(root->right); 42 | 43 | //inorder 44 | printTree(root->left); 45 | printf("%d ", root->val); 46 | printTree(root->right); 47 | 48 | //postorder 49 | // printTree(root->right); 50 | // printTree(root->left); 51 | // printf("%d ", root->val); 52 | 53 | 54 | } -------------------------------------------------------------------------------- /2024-2025/10b/2025-05-27-des-1/index.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "helpers.h" 5 | 6 | // Always uses the rightmost size bits of input and output 7 | // With input 0b0000000010101010 and perm { 1, 3, 5, 7, 2, 4, 6, 8 } 8 | // The output will be 0b0000000011110000 9 | uint64_t permute(uint64_t input, uint8_t *perm, uint8_t size) { 10 | uint64_t output = 0; 11 | 12 | for(int i = 0; i < size; i++) { 13 | uint64_t bit = (input >> (size - perm[i])) & 1; 14 | output |= (bit << (size - i - 1)); 15 | } 16 | 17 | return output; 18 | } 19 | 20 | int main() { 21 | uint64_t input = 0b10101010; // 170 22 | uint8_t perm[] = { 1, 3, 5, 7, 2, 4, 6, 8 }; 23 | uint8_t size = 8; 24 | uint64_t expected = 0b11110000; // 240; 25 | 26 | uint64_t result = permute(input, perm, size); 27 | 28 | printf("Input: %lu (0x%lx)\n", input, input); 29 | printBits(sizeof(input), &input); 30 | printf("Expected: %lu (0x%lx)\n", expected, expected); 31 | printBits(sizeof(expected), &expected); 32 | printf("Result: %lu (0x%lx)\n", result, result); 33 | printBits(sizeof(result), &result); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /2022-2023/10b/2023-01-11-graph-1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node_t { 5 | // struct node_t** connections; 6 | // int count; 7 | 8 | struct vector_t connections; 9 | }; 10 | 11 | void connect_nodes(struct node_t* a, struct node_t* b) { 12 | vector_add(a->connections, b); 13 | vector_add(b->connections, a); 14 | } 15 | 16 | int main() { 17 | /*struct node_t n1; 18 | struct node_t n2; 19 | struct node_t n3; 20 | struct node_t n4; 21 | 22 | connect_nodes(&n1, &n2); 23 | connect_nodes(&n2, &n3); 24 | connect_nodes(&n3, &n1); 25 | connect_nodes(&n3, &n4);*/ 26 | 27 | int matrix[][] = { 28 | {0, 1, 1, 0}, 29 | {1, 0, 1, 0}, 30 | {1, 1, 0, 1}, 31 | {0, 0, 1, 0} 32 | }; 33 | 34 | struct vector_t nodes; 35 | for(int i = 0; i < 4; i++) { 36 | struct node_t* new_node = malloc(sizeof(struct node_t)); 37 | vector_add(nodes, new_node); 38 | } 39 | 40 | for(int i = 1; i < 4; i++) { 41 | for(int j = 0; j < i; j++) { 42 | if(matrix[i][j] == 1) 43 | connect_nodes( 44 | vector_get(nodes, i), 45 | vector_get(nodes, j) 46 | ); 47 | } 48 | } 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /2024-2025/10a/2024-11-07-trees/tree.c: -------------------------------------------------------------------------------- 1 | #include "tree.h" 2 | #include 3 | #include 4 | 5 | //Binary Search Tree 6 | Node* create_node(int val) { 7 | Node* node = (Node*)malloc(sizeof(Node)); 8 | node->left = NULL; 9 | node->right = NULL; 10 | node->val = val; 11 | 12 | return node; 13 | } 14 | 15 | // O(h) 16 | Node* bst_insert(Node* root, int v) { 17 | if (root == NULL) { 18 | return create_node(v); 19 | } 20 | 21 | if (root->val < v) { 22 | root->left = bst_insert(root->left, v); 23 | } 24 | else { 25 | root->right = bst_insert(root->right, v); 26 | } 27 | 28 | return root; 29 | } 30 | 31 | 32 | // O(n) 33 | void printTree(Node* root) { 34 | if (root == NULL) { 35 | return; 36 | } 37 | 38 | //preorder 39 | // printf("%d ", root->val); 40 | // printTree(root->left); 41 | // printTree(root->right); 42 | 43 | //inorder 44 | printTree(root->left); 45 | printf("%d ", root->val); 46 | printTree(root->right); 47 | 48 | //postorder 49 | // printTree(root->right); 50 | // printTree(root->left); 51 | // printf("%d ", root->val); 52 | 53 | 54 | } -------------------------------------------------------------------------------- /2025-2026/10a/utils/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | Node* init_node(int val) { 6 | Node* node = (Node*)malloc(sizeof(Node)); 7 | node->val = val; 8 | node->next = NULL; 9 | 10 | return node; 11 | } 12 | Stack* init_stack() { 13 | Stack* stack = (Stack*)malloc(sizeof(Stack)); 14 | stack->top = NULL; 15 | 16 | return stack; 17 | } 18 | 19 | void push(Stack* stack, int val) { 20 | Node* new_node = init_node(val); 21 | new_node->next = stack->top; 22 | stack->top = new_node; 23 | } 24 | 25 | int pop(Stack* stack) { 26 | if (stack->top == NULL) { 27 | printf("List already empty"); 28 | exit(1); 29 | } 30 | 31 | Node* currentTop = stack->top; 32 | int res = currentTop->val; 33 | stack->top = currentTop->next; 34 | free(currentTop); 35 | 36 | return res; 37 | } 38 | 39 | void printStack(Stack* stack) { 40 | Node* it = stack->top; 41 | 42 | while(it != NULL) { 43 | printf("%d ", it->val); 44 | it = it->next; 45 | } 46 | printf("\n"); 47 | } 48 | 49 | bool isEmpty(Stack* stack) { 50 | return stack->top == NULL; 51 | } -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-15-stack/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "stack.h" 4 | 5 | Node* init_node(int val) { 6 | Node* node = (Node*)malloc(sizeof(Node)); 7 | node->val = val; 8 | node->next = NULL; 9 | 10 | return node; 11 | } 12 | Stack* init_stack() { 13 | Stack* stack = (Stack*)malloc(sizeof(Stack)); 14 | stack->top = NULL; 15 | 16 | return stack; 17 | } 18 | 19 | void push(Stack* stack, int val) { 20 | Node* new_node = init_node(val); 21 | new_node->next = stack->top; 22 | stack->top = new_node; 23 | } 24 | 25 | int pop(Stack* stack) { 26 | if (stack->top == NULL) { 27 | printf("List already empty"); 28 | exit(1); 29 | } 30 | 31 | Node* currentTop = stack->top; 32 | int res = currentTop->val; 33 | stack->top = currentTop->next; 34 | free(currentTop); 35 | 36 | return res; 37 | } 38 | 39 | void printStack(Stack* stack) { 40 | Node* it = stack->top; 41 | 42 | while(it != NULL) { 43 | printf("%d ", it->val); 44 | it = it->next; 45 | } 46 | printf("\n"); 47 | } 48 | 49 | bool isEmpty(Stack* stack) { 50 | return stack->top == NULL; 51 | } -------------------------------------------------------------------------------- /2023-2024/10b/2023-10-09-insertion-sort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void swap(int* left, int* right) { 7 | int tmp = *left; 8 | *left = *right; 9 | *right = tmp; 10 | } 11 | 12 | void insertion_sort(int* arr, int count) { 13 | for(int i = 1; i < count; i++) { 14 | int j = i - 1; 15 | while(arr[i] < arr[j]) {j--;} 16 | 17 | int tmp = arr[i]; 18 | int copyStart = j+1; 19 | int copyEnd = i-1; 20 | 21 | memmove( 22 | arr + copyStart, 23 | arr + copyStart + 1, 24 | (copyEnd - copyStart) * sizeof(int) 25 | ); 26 | arr[j + 1] = tmp; 27 | } 28 | } 29 | 30 | int* create_array(int count) { 31 | int* arr = malloc(sizeof(int) * count); 32 | 33 | for(int i = 0; i < count; i++) 34 | arr[i] = random(); 35 | 36 | return arr; 37 | } 38 | 39 | int main() { 40 | srand(time(NULL)); 41 | 42 | int* list = create_array(5); 43 | 44 | insertion_sort(list, 5); 45 | 46 | for(int i = 0; i < 5; i++) { 47 | printf("arr[%d] = %d\n", i, list[i]); 48 | } 49 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-04-03-compression-2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int code_exists(vector_t* codes, uint8_t* data) { 6 | for(int i =0; i < codes->length; i++) { 7 | uint8_t* tmp = vector_get(codes, i); 8 | for(int j = 0; j < ???; j++) { 9 | if(tmp[j] != data[j]) break; 10 | } 11 | return 1; 12 | } 13 | 14 | return 0; 15 | } 16 | 17 | uint8_t* compress(uint8_t* data, uint32_t size) { 18 | vector_t* codes = vector_init(); 19 | 20 | for(uint32_t i = 0; i < size; i++) { 21 | uint8_t tmp[1]; 22 | tmp[0] = data[i]; 23 | 24 | if(!code_exists(codes, tmp)) 25 | vector_add(codes, tmp); 26 | } 27 | 28 | for(uint32_t l = 2; l < size/2; l++) 29 | for(uint32_t i = 0; i < size - 1; i++) { 30 | uint8_t tmp[l]; 31 | memcpy(tmp, data + i, l); 32 | 33 | for(uint32_t j = i + l; j < size - 1; j++) { 34 | uint8_t tmp2[l]; 35 | memcpy(tmp2, data + j, l); 36 | 37 | if(arr_compare(tmp, tmp2) && !code_exists(codes, tmp)) { 38 | vector_add(codes, tmp); 39 | break; 40 | } 41 | } 42 | } 43 | 44 | return NULL; 45 | } 46 | 47 | int main() { 48 | return 0; 49 | }; 50 | -------------------------------------------------------------------------------- /2023-2024/10a/utils/graph_matrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "graph_matrix.h" 4 | 5 | Graph *init_graph(int numVertices) 6 | { 7 | Graph *graph = (Graph *)malloc(sizeof(Graph)); 8 | graph->numVertices = numVertices; 9 | graph->adjMatrix = (int **)malloc(numVertices * sizeof(int *)); 10 | 11 | for (int i = 0; i < numVertices; i++) 12 | { 13 | graph->adjMatrix[i] = (int *)calloc(numVertices, sizeof(int)); 14 | } 15 | 16 | return graph; 17 | } 18 | 19 | void addEdgeDirectional(Graph *graph, int from, int to) 20 | { 21 | if (from < 0 || from >= graph->numVertices || to < 0 || to >= graph->numVertices) 22 | { 23 | printf("Invalid from or to\n"); 24 | return; 25 | } 26 | 27 | graph->adjMatrix[from][to] = 1; 28 | } 29 | 30 | void addEdge(Graph *graph, int from, int to) 31 | { 32 | addEdgeDirectional(graph, from, to); 33 | addEdgeDirectional(graph, to, from); 34 | } 35 | 36 | void printGraph(Graph *graph) 37 | { 38 | for (int i = 0; i < graph->numVertices; i++) 39 | { 40 | for (int j = 0; j < graph->numVertices; j++) 41 | { 42 | printf("%d ", graph->adjMatrix[i][j]); 43 | } 44 | printf("\n"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /2022-2023/10b/2023-04-24-lzw-1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | uint8_t* compress(uint8_t* data, uint32_t size) { 6 | vector_t* codes = vector_init(); 7 | 8 | for(uint32_t i = 0; i < 3; i++) { 9 | uint8_t tmp[1]; 10 | tmp[0] = 'a' + i; 11 | 12 | vector_add(codes, tmp); 13 | } 14 | 15 | uint8_t* out = malloc(size); 16 | for(uint32_t i = 0; i < size; i++) { 17 | vector_t* tmp = vector_init(); 18 | vector_add(tmp, data[i]); 19 | 20 | while(code_exists(codes, tmp->value)) { 21 | vector_add(tmp, data[i + ?]); 22 | } 23 | 24 | vector_add(codes, tmp->value); 25 | 26 | vector_pop(tmp); 27 | out[outLen++] = vector_index_of(codes, tmp->value); 28 | i += ?; 29 | } 30 | 31 | return out; 32 | } 33 | 34 | uint8_t* decompress(uint8_t* data, uint32_t size) { 35 | return NULL; 36 | } 37 | 38 | int main() { 39 | uint8_t* data = "aaaaabcabc"; 40 | 41 | uint8_t* compressed = compress(data, 10); 42 | uint8_t* decompressed = decompress(compressed, 10); 43 | 44 | printf("Input: %s\n", data); 45 | printf("Compressed: %s\n", compressed); 46 | printf("Decmpressed: %s\n", decompressed); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-04-Insertion_sort_and_lists/dlist.h: -------------------------------------------------------------------------------- 1 | #ifndef DLIST_H 2 | #define DLIST_H 3 | 4 | typedef struct Node 5 | { 6 | int value; 7 | struct Node *next; 8 | struct Node *prev; 9 | } Node; 10 | 11 | /* 12 | Много често за удобство се пази и края на списъка. Така можем да добавяме/махаме бързо както от началото така и от края. 13 | Понякога дори има и трети указател сечощ към "текущ" елемент, които може да местим наляво надясно и да служи за итератор, 14 | чрез който бързо да махаме и добавяме някъде по-средата на масива. 15 | 16 | Важното, което да запомним е, че може да си модифицираме списъка както си искаме - едносвързан, двузвързан, да пазим начало, край, текущ, 17 | да е цикличен и т.н. В зависимост от начина по-който се очаква да го използваме прецаняме какво ни трябва. 18 | */ 19 | 20 | typedef struct DList 21 | { 22 | Node *head; 23 | Node *tail; 24 | } DList; 25 | 26 | DList *init_dlist(); 27 | void insertBegin(DList *, int); 28 | void insertEnd(DList *, int); 29 | 30 | int getAt(DList *, int); 31 | void clear(DList *); 32 | int pop(DList *); 33 | void printDList(DList *); 34 | void printDListReverse(DList *); 35 | int popFront(DList *); 36 | 37 | void insertAt(DList *, int, int); 38 | int removeAt(DList *, int); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-29-huffman-coding/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "map.h" 3 | 4 | void huffman_encode(char* str, map_t* letters) { 5 | char* result = malloc(strlen(str)); 6 | 7 | int byte_count = 0; 8 | int bit_count = 0; 9 | for(int i = 0; i < strlen(str); i++) { 10 | char curr_value = str[i]; 11 | char code = map_get(letters, curr_value); 12 | 13 | // result[byte_count] <<= 3; 14 | // char code_left = code >> 2; 15 | // char code_right = code & 0b00000011; 16 | // result[byte_count] = result[byte_count] | code_left; 17 | // result[++byte_count] |= code_right; 18 | 19 | // 00000101 << 5 = 10100000 20 | // 00000101 << 2 = 00010100 21 | char code_left = code << (8 - bit_count - 3); 22 | result[byte_count] |= code; 23 | bit_count += 3; 24 | } 25 | 26 | result = realloc(result, byte_count); 27 | } 28 | 29 | int main() { 30 | map_t* letters = init_map(10); 31 | 32 | map_add(letters, "A", 0b000); 33 | map_add(letters, "B", 0b010); 34 | map_add(letters, "C", 0b110); 35 | map_add(letters, "D", 0b111); 36 | 37 | char* str = "ABCDAAB"; 38 | 39 | huffman_encode(str, letters); 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-10-17-conuntingsort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void counting_sort(int* arr, unsigned int size) { 6 | //int min = 0; 7 | //int max = 10; 8 | 9 | int min = arr[0]; 10 | int max = arr[0]; 11 | for(int i = 1; i < size; i++) { 12 | if(arr[i] > max) max = arr[i]; 13 | if(arr[i] < min) min = arr[i]; 14 | } 15 | printf("min=%d, max=%d\n", min, max); 16 | 17 | int counter_count = abs(min) + abs(max) + 1; 18 | int* counters = calloc(counter_count, sizeof(int)); 19 | //malloc(sizeof(int) * (max + 1)); 20 | //memset(counters, 0, sizeof(int) * (max + 1); 21 | 22 | for(int i = 0; i < size; i++) 23 | counters[arr[i] - min]++; 24 | //-3 - (-3) = -3 + 3 = 0 25 | //3 - (3) = 3 - 3 = 0 26 | 27 | int j = 0; 28 | for(int i = 0; i < max; i++) 29 | for(int k = 0; k < counters[i]; k++) 30 | arr[j++] = i + min; 31 | //0 + (-3) = -3 32 | //0 + (3) = 3 33 | } 34 | 35 | int main() { 36 | int arr[] = {6, 3, -2, 7, 3, 4, 4, 8, 3, 6}; 37 | 38 | for(int i = 0; i < 10; i++) 39 | printf("[%d] %d ", i, arr[i]); 40 | puts(""); 41 | 42 | counting_sort(arr, 10); 43 | 44 | for(int i = 0; i < 10; i++) 45 | printf("[%d] %d ", i, arr[i]); 46 | puts(""); 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /2023-2024/10a/2023-10-25-skip-list/skip_list.h: -------------------------------------------------------------------------------- 1 | #ifndef SKIP_LISTH 2 | #define SKIP_LISTH 3 | 4 | #define MAX_LEVEL 16 5 | 6 | /* 7 | За по-лесно директно зададохме константен MAX_LEVEL и масив с такъв размер. Иначе трябваше да се занимаваме динамично да го алокираме и следим 8 | Това разбира се увеличава използваната памет с 16 указателя за всеки Node. Не е прекалено фрапиращо, особено ако данните, които пазим не са просто един int, 9 | а някакъв по-сложен обект, на чийто фон тези 16 указателя да нямат толкова значение. Но най-добре би било да се алокират динамично. 10 | Тогава освен основните n Node-a на нулево ниво, допълнителната памет би била следната: 11 | 1/2 Node-ове на второ ниво 12 | 1/4 на трето 13 | 1/8 на четвърто и т.н 14 | 1/2 + 1/4 + 1/8 + ... = 1 15 | 16 | Общата допълнителна памет е отново n, а цялата с нулево ниво - само 2n. 17 | 18 | */ 19 | typedef struct Node 20 | { 21 | int value; 22 | struct Node *next[MAX_LEVEL]; 23 | } Node; 24 | 25 | typedef struct SkipList 26 | { 27 | Node *head; 28 | } SkipList; 29 | 30 | SkipList *init_list(); 31 | void clear(SkipList *list); 32 | void printList(SkipList *list); 33 | 34 | void sl_insert(SkipList *list, int val); 35 | Node *sl_search(SkipList *list, int val); 36 | Node *sl_remove(SkipList *list, int val); 37 | 38 | #endif -------------------------------------------------------------------------------- /2024-2025/10a/utils/graph.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "graph.h" 4 | 5 | 6 | Vertex* init_vertex(int val, int weight) { 7 | Vertex* vertex = (Vertex*)malloc(sizeof(Vertex)); 8 | vertex->val = val; 9 | vertex->weight = weight; 10 | vertex->next = NULL; 11 | 12 | return vertex; 13 | } 14 | 15 | Graph* init_graph(int numVertices) { 16 | Graph *graph = (Graph*)malloc(sizeof(Graph)); 17 | graph->numVertices = numVertices; 18 | graph->adjList = (Vertex**)calloc(numVertices, sizeof(Vertex*)); 19 | 20 | return graph; 21 | } 22 | 23 | void addEdgeDirectional(Graph*graph, int from, int to, double weight) { 24 | Vertex* new_vertex = init_vertex(to, weight); 25 | new_vertex->next = graph->adjList[from]; 26 | graph->adjList[from] = new_vertex; 27 | } 28 | 29 | void addEdge(Graph* graph, int from, int to, double weight) { 30 | addEdgeDirectional(graph, from, to, weight); 31 | addEdgeDirectional(graph, to, from, weight); 32 | } 33 | 34 | void printGraph(Graph *graph) { 35 | for (int i = 0; i < graph->numVertices; i++) { 36 | Vertex* it = graph->adjList[i]; 37 | printf("Neighbors of %d: ", i); 38 | while (it != NULL) 39 | { 40 | printf("%d ", it->val); 41 | it = it->next; 42 | } 43 | printf("\n"); 44 | } 45 | } -------------------------------------------------------------------------------- /2023-2024/10a/2024-06-05-lzw/lzw.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../utils/hash.h" 4 | #include "../utils/vector.h" 5 | 6 | vector_t *lzw(char *text) 7 | { 8 | HashMap *dict = init_hash_map(); 9 | ; 10 | int dict_size = 256; 11 | for (int i = 0; i < 256; i++) 12 | { 13 | char *key = (char *)malloc(2); 14 | key[0] = i; 15 | key[1] = '\0'; 16 | printf("%i\n", i); 17 | setInt(dict, key, i); 18 | } 19 | 20 | vector_t *result = init_vector(); 21 | char *w = (char *)malloc(256); 22 | int word_size = 0; 23 | 24 | for (int i = 0; text[i] != '\0'; i++) 25 | { 26 | w[word_size++] = text[i]; 27 | w[word_size] = '\0'; 28 | 29 | printf("%d\n", getInt(dict, w)); 30 | if (getInt(dict, w) != -1) 31 | { 32 | continue; 33 | } 34 | else 35 | { 36 | setInt(dict, w, dict_size++); 37 | 38 | w[word_size - 1] = '\0'; 39 | push_back(result, getInt(dict, w)); 40 | 41 | w[0] = text[i]; 42 | w[1] = '\0'; 43 | word_size = 1; 44 | } 45 | } 46 | 47 | return result; 48 | } 49 | 50 | int main() 51 | { 52 | char *text = "ABABABA"; 53 | vector_t *result = lzw(text); 54 | printVector(result); 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-12-13-exam2-solution/ver2/linked_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "linked_list.h" 4 | 5 | struct list_node_t* init_list_node( 6 | int value 7 | ) { 8 | struct list_node_t* node = malloc(sizeof(struct list_node_t)); 9 | 10 | node->value = value; 11 | node->next = node->tail = NULL; 12 | 13 | return node; 14 | } 15 | 16 | struct list_node_t* push_list( 17 | struct list_node_t* head, 18 | int value 19 | ) { 20 | struct list_node_t* new_node = init_list_node(value); 21 | 22 | // If the list is empty create a new head and point tail to itself 23 | if(head == NULL) { 24 | new_node->tail = new_node; 25 | return new_node; 26 | } 27 | 28 | // Add to the end of the list 29 | struct list_node_t* curr = head->tail; 30 | 31 | curr->next = new_node; 32 | head->tail = curr->next; 33 | 34 | return head; 35 | } 36 | 37 | int pop_list(struct list_node_t** head) { 38 | // Helper var for mbette readability 39 | struct list_node_t* head_ref = *head; 40 | 41 | if(head_ref == NULL) return 0; 42 | 43 | int value = head_ref->value; 44 | 45 | // Ensure the next tail pointer points to the correct tail 46 | if(head_ref->next != NULL) 47 | head_ref->next->tail = head_ref->tail; 48 | 49 | // Redirect the original head pointer to the next item 50 | (*head) = head_ref->next; 51 | 52 | return value; 53 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-11-29-tree4/queue.c: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | #include 3 | #include 4 | 5 | QueueNode *create_node(Node *val) 6 | { 7 | QueueNode *node = (QueueNode *)malloc(sizeof(QueueNode)); 8 | node->val = val; 9 | node->next = NULL; 10 | 11 | return node; 12 | } 13 | 14 | Queue *init_queue() 15 | { 16 | Queue *queue = (Queue *)malloc(sizeof(Queue)); 17 | queue->front = NULL; 18 | queue->rear = NULL; 19 | } 20 | 21 | void enqueue(Queue *queue, Node *val) 22 | { 23 | QueueNode *node = create_node(val); 24 | if (queue->front == NULL) 25 | { 26 | queue->rear = queue->front = node; 27 | return; 28 | } 29 | 30 | queue->rear->next = node; 31 | queue->rear = node; 32 | } 33 | 34 | Node *dequeue(Queue *queue) 35 | { 36 | if (queue->front == NULL) 37 | { 38 | printf("Queue is empty.\n"); 39 | exit(1); 40 | } 41 | 42 | QueueNode *front = queue->front; 43 | 44 | Node *val = front->val; 45 | QueueNode *tmp = front; 46 | queue->front = front->next; 47 | // free(tmp); 48 | 49 | if (queue->front == NULL) 50 | { 51 | queue->rear = NULL; 52 | } 53 | 54 | return val; 55 | } 56 | 57 | void clear_queue(Queue *queue) 58 | { 59 | while (queue->front != NULL) 60 | { 61 | dequeue(queue); 62 | } 63 | 64 | free(queue); 65 | } -------------------------------------------------------------------------------- /2023-2024/10a/2024-04-17-dsu_leet_code/path_exists.c: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-if-path-exists-in-graph/ 2 | typedef struct Subset 3 | { 4 | int parent; 5 | int rank; 6 | } Subset; 7 | 8 | int Find(Subset *subsets, int i) 9 | { 10 | if (subsets[i].parent == i) 11 | { 12 | return i; 13 | } 14 | 15 | return Find(subsets, subsets[i].parent); 16 | } 17 | 18 | void Union(Subset *subsets, int src, int dest) 19 | { 20 | int root1 = Find(subsets, src); 21 | int root2 = Find(subsets, dest); 22 | 23 | if (subsets[root1].rank < subsets[root2].rank) 24 | { 25 | subsets[root1].parent = root2; 26 | } 27 | else if (subsets[root1].rank > subsets[root2].rank) 28 | { 29 | subsets[root2].parent = root1; 30 | } 31 | else 32 | { 33 | subsets[root2].parent = root1; 34 | } 35 | 36 | bool validPath(int n, int **edges, int edgesSize, int *edgesColSize, int source, int destination) 37 | { 38 | Subset *subsets = (Subset *)malloc(n * sizeof(Subset)); 39 | for (int i = 0; i < n; i++) 40 | { 41 | subsets[i] = (Subset){i, 0}; 42 | } 43 | 44 | for (int i = 0; i < edgesSize; i++) 45 | { 46 | Union(subsets, edges[i][0], edges[i][1]); 47 | } 48 | 49 | return Find(subsets, source) == Find(subsets, destination); 50 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-18-dijkstra-2/priority_queue.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct queue_t { 4 | void** nodes; 5 | int size; 6 | int (*compare)(void*, void*); 7 | }; 8 | 9 | typedef struct queue_t queue_t; 10 | 11 | queue_t* priority_queue(int (*compare)(void*, void*)) { 12 | queue_t* q = malloc(sizeof(queue_t)); 13 | q->nodes = NULL; 14 | q->size = 0; 15 | q->compare = compare; 16 | 17 | return q; 18 | } 19 | 20 | void push_queue(queue_t* q, void* value) { 21 | q->size++; 22 | q->nodes = realloc(q->nodes, q->size * sizeof(void*)); 23 | q->nodes[q->size-1] = value; 24 | } 25 | 26 | void* pop_queue(queue_t* q) { 27 | int smallest_index = 0; 28 | 29 | for(int i = 1; i < q->size; i++) 30 | if(q->compare( 31 | q->nodes[i], 32 | q->nodes[smallest_index] 33 | ) < 0) 34 | smallest_index = i; 35 | 36 | void* value = q->nodes[smallest_index]; 37 | 38 | for(int i = smallest_index + 1; i < q->size; i++) 39 | q->nodes[i-1] = q->nodes[i]; 40 | 41 | q->size--; 42 | 43 | return value; 44 | } 45 | 46 | // int a = 5; 47 | // int* b = &a; 48 | // int *c = &a; 49 | // int* d, e, f; 50 | // int *d, e, f; 51 | 52 | // void a() {} 53 | // void (*b)() = &a; 54 | 55 | // int c(int a1, char a2) {} 56 | // int (*d)(int, char) = c; -------------------------------------------------------------------------------- /2023-2024/10b/2024-02-19-graph-1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "graph.h" 4 | 5 | int main() { 6 | // list_t* list = init_list(); 7 | // push_list(list, 1); 8 | // push_list(list, 2); 9 | 10 | // for(int i = 0; i < 3; i++) 11 | // printf("%d\n", list_get_at(list, i)); 12 | 13 | // graph_node_t* node1 = init_graph_node("Pencho"); 14 | // printf("%s\n", node1->name); 15 | 16 | // graph_t* graph = init_graph(); 17 | 18 | // add_graph_node(graph, "Pencho"); 19 | // add_graph_node(graph, "Gencho"); 20 | // add_graph_node(graph, "Penka"); 21 | 22 | // connect_nodes( 23 | // find_node_by_name(graph, "Pencho"), 24 | // find_node_by_name(graph, "Gencho") 25 | // ); 26 | // connect_nodes( 27 | // find_node_by_name(graph, "Gencho"), 28 | // find_node_by_name(graph, "Penka") 29 | // ); 30 | // connect_nodes( 31 | // find_node_by_name(graph, "Pencho"), 32 | // find_node_by_name(graph, "Penka") 33 | // ); 34 | 35 | // print_graph(graph); 36 | 37 | char* input_data[] = { 38 | "3", 39 | "Pencho Gencho Penka", 40 | "0 1 1", 41 | "1 0 1", 42 | "1 1 0" 43 | }; 44 | 45 | graph_t* graph = init_graph_from_strings(input_data); 46 | print_graph(graph); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /2023-2024/10b/2023-10-23-skip-list/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct list_t { 5 | int value; 6 | struct list_t* next; 7 | struct list_t* skip; 8 | }; 9 | typedef struct list_t list_t; 10 | 11 | list_t* init_list(int value) { 12 | list_t* list = (list_t*)malloc(sizeof(list_t)); 13 | 14 | list->value = value; 15 | list->next = NULL; 16 | list->skip = NULL; 17 | 18 | return list; 19 | } 20 | 21 | void push_list(list_t* list, int value) { 22 | if(list->next == NULL) { 23 | list->next = init_list(value); 24 | } else { 25 | push_list(list->next, value); 26 | if(list->skip != NULL && list->next != NULL && list->next->next != NULL) 27 | list->skip = list->next->next; 28 | } 29 | } 30 | 31 | int main() { 32 | list_t* list = init_list(1); 33 | // list->next = init_list(2); 34 | // list->next->next = init_list(3); 35 | // push_list(list, 2); 36 | // push_list(list, 3); 37 | 38 | list_t* head = list; 39 | for(int i = 2; i < 6; i++) { 40 | push_list(list, i); 41 | // head = head->next; 42 | } 43 | 44 | head = list; 45 | for(int i = 0; i < 5; i++) { 46 | printf("list[%d](%p) = %d next=%p skip=%p\n", i, head, head->value, head->next, head->skip); 47 | head = head->next; 48 | } 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /2025-2026/10a/2025-09-29-vector/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "vector.h" 4 | 5 | int main() { 6 | vector* v = init_vector(); 7 | 8 | push(v, 1); 9 | push(v, 2); 10 | push(v, 3); 11 | push(v, 4); 12 | push(v, 5); 13 | 14 | print_vector(v); 15 | printf("%d \n", pop(v)); 16 | print_vector(v); 17 | pop(v); 18 | pop(v); 19 | pop(v); 20 | 21 | print_vector(v); 22 | push(v, 10); 23 | push(v, 20); 24 | print_vector(v); 25 | 26 | pushFront(v, 5); 27 | print_vector(v); 28 | printf("at front %d\n", popFront(v)); 29 | print_vector(v); 30 | 31 | free_vector(v); 32 | 33 | //BubbleSort 34 | vector* v2 = init_vector(); 35 | push(v2, 10); 36 | push(v2, 15); 37 | push(v2, 6); 38 | push(v2, 2); 39 | push(v2, 20); 40 | push(v2, 25); 41 | push(v2, 30); 42 | 43 | for (int j = 0; j < v2->size - 1; j++) { 44 | bool hasSwapped = false; 45 | for (int i = 0; i < v2->size - 1 - j; i++) { 46 | if (v2->data[i] > v2->data[i + 1]) { 47 | int c = v2->data[i]; 48 | v2->data[i] = v2->data[i + 1]; 49 | v2->data[i+1] = c; 50 | hasSwapped = true; 51 | } 52 | } 53 | 54 | if (!hasSwapped) { 55 | break; 56 | } 57 | } 58 | 59 | print_vector(v2); 60 | 61 | 62 | return 0; 63 | } -------------------------------------------------------------------------------- /2024-2025/10a/2024-12-2-heap/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../utils/vector.h" 4 | 5 | void swap(int* a, int *b) { 6 | int c = *b; 7 | *b = *a; 8 | *a = c; 9 | } 10 | 11 | int siftUp(vector*v, int i) { 12 | int parent = 0; 13 | if (i % 2 == 1) { 14 | parent = i / 2; 15 | } else if (i > 0) { 16 | parent = i / 2 - 1; 17 | } 18 | 19 | if (v->arr[parent] < v->arr[i]) { 20 | swap(&v->arr[parent], &v->arr[i]); 21 | siftUp(v, parent); 22 | } 23 | } 24 | 25 | int siftDown(vector* v, int i) { 26 | int left = 2*i + 1; 27 | int right = 2*i + 2; 28 | int maxIndex; 29 | 30 | if (left < v->size) { 31 | maxIndex = left; 32 | } 33 | if (right < v->size && v->arr[right] > v->arr[maxIndex]) { 34 | maxIndex = right; 35 | } 36 | 37 | if (v->arr[i] < v->arr[maxIndex]) { 38 | swap(&v->arr[i], &v->arr[maxIndex]); 39 | siftDown(v, maxIndex); 40 | } 41 | } 42 | 43 | int extractMax(vector* v) { 44 | int val = v->arr[0]; 45 | 46 | v->arr[0] = v->arr[v->size-1]; 47 | pop(v); 48 | siftDown(v, 0); 49 | 50 | return val; 51 | } 52 | 53 | void insert(vector* v, int val) { 54 | push(v, val); 55 | siftUp(v, v->size - 1); 56 | } 57 | void heapify(vector *v) { 58 | for (int i = 0; i < v->size; i++) { 59 | siftUp(v, i); 60 | } 61 | } 62 | 63 | int main() { 64 | 65 | return 0; 66 | } -------------------------------------------------------------------------------- /2025-2026/10b/2025-09-29-bubblesort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int bubble_sort(int arr[], int n) { 4 | int changes = 1; 5 | while(changes == 1) { 6 | // printf("New pass through the array\n"); 7 | changes = 0; 8 | for(int i = 0; i < n-1; i++) { 9 | printf("Comparing %d and %d\n", arr[i], arr[i+1]); 10 | if(arr[i] > arr[i+1]) { 11 | printf("Swapping %d and %d\n", arr[i], arr[i+1]); 12 | int temp = arr[i]; 13 | arr[i] = arr[i+1]; 14 | arr[i+1] = temp; 15 | 16 | // printf("It has changes now\n"); 17 | changes = 1; 18 | } 19 | } 20 | } 21 | } 22 | 23 | 24 | 25 | int insertion_sort(int arr[], int n) { 26 | for(; n > 1; n--) { 27 | for(int i = 0; i < n-1; i++) { 28 | printf("Comparing %d and %d\n", arr[i], arr[i+1]); 29 | if(arr[i] > arr[i+1]) { 30 | printf("Swapping %d and %d\n", arr[i], arr[i+1]); 31 | int temp = arr[i]; 32 | arr[i] = arr[i+1]; 33 | arr[i+1] = temp; 34 | } 35 | } 36 | } 37 | } 38 | 39 | 40 | 41 | int main() { 42 | int arr[] = {5, 3, 8, 4, 2}; 43 | int n = sizeof(arr)/sizeof(arr[0]); 44 | 45 | for(int i = 0; i < n; i++) { 46 | printf("%d ", arr[i]); 47 | } 48 | printf("\n"); 49 | insertion_sort(arr, n); 50 | 51 | for(int i = 0; i < n; i++) { 52 | printf("%d ", arr[i]); 53 | } 54 | printf("\n"); 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /2022-2023/10b/2023-06-05-encryption-2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | unsigned char* add_int(unsigned char* str, int a) { 6 | unsigned char* out = malloc(strlen(str) + 1); 7 | 8 | for(int i = 0; i < strlen(str); i++) { 9 | out[i] = (str[i] + a) % 256; 10 | } 11 | 12 | out[strlen(str) + 1] = '\0'; 13 | return out; 14 | } 15 | 16 | unsigned char* table_method(unsigned char* str, int a) { 17 | unsigned char* out = malloc(strlen(str) + 1); 18 | 19 | for(int i = 0; i < strlen(str); i++) { 20 | int y = i / a; 21 | int x = x % a; 22 | 23 | int y2 = x; 24 | int x2 = y; 25 | 26 | int n = y2 * (strlen(str) / a) + x2; 27 | out[n] = str[i]; 28 | 29 | // int n = (x % a) * (strlen(str) / a) + (i / a); 30 | // out[(x % a) * (strlen(str) / a) + (i / a)] = str[i]; 31 | } 32 | 33 | out[strlen(str) + 1] = '\0'; 34 | return out; 35 | } 36 | 37 | int main() { 38 | unsigned char* str = "hello 10b"; 39 | 40 | unsigned char* out_1 = add_int(str, 3); 41 | unsigned char* out_2 = table_method(str, 4); 42 | unsigned char* out_3 = table_method( 43 | add_int(str, 3), 44 | 4 45 | ); 46 | 47 | printf("\"%s\"\n", str); 48 | printf("\"%s\"\n", out_1); 49 | printf("\"%s\"\n", out_2); 50 | printf("\"%s\"\n", out_3); 51 | 52 | return 0; 53 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-09-26-revision-3/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "list.h" 5 | 6 | struct list_node_t * create_node(int value) { 7 | struct list_node_t *new_node = malloc( 8 | sizeof(struct list_node_t) 9 | ); 10 | 11 | new_node->value = new_value; 12 | new_node->next = NULL; 13 | 14 | return new_node; 15 | } 16 | 17 | void print_list(struct list_node_t *head) { 18 | while(head != NULL) { 19 | printf("%d\n", head->value); 20 | head = head->next; 21 | } 22 | } 23 | 24 | struct list_node_t * push_front(struct list_node_t *head, int new_value) { 25 | /*struct list_node_t *new_node = malloc( 26 | sizeof(struct list_node_t) 27 | ); 28 | 29 | new_node->value = new_value;*/ 30 | struct list_node_t *new_node = create_node(new_value); 31 | new_node->next = head; 32 | 33 | // head = new_node; 34 | return new_node; 35 | } 36 | 37 | struct list_node_t * push_back(struct list_node_t *head, int new_value) { 38 | /*struct list_node_t *new_node = malloc( 39 | sizeof(struct list_node_t) 40 | ); 41 | 42 | new_node->value = new_value; 43 | new_node->next = NULL;*/ 44 | if(head == NULL) return push_front(NULL, new_value); 45 | 46 | struct list_node_t *new_node = create_node(new_value); 47 | 48 | struct list_node_t *tail = head; 49 | /*while(tail->next != NULL) { 50 | tail = tail->next; 51 | }*/ 52 | for(; tail->next != NULL; tail = tail->next); 53 | 54 | tail->next = new_node; 55 | 56 | return head; 57 | } -------------------------------------------------------------------------------- /2024-2025/10a/utils/graph_h.c: -------------------------------------------------------------------------------- 1 | #include "hashmap.h" 2 | #include "graph_h.h" 3 | #include 4 | #include 5 | 6 | Vertex* init_vertex(char* val, double weight) { 7 | Vertex* vertex = (Vertex*)malloc(sizeof(Vertex)); 8 | vertex->val = val; 9 | vertex->weight = weight; 10 | vertex->next = NULL; 11 | 12 | return vertex; 13 | } 14 | 15 | Graph* init_graph() { 16 | Graph *graph = (Graph*)malloc(sizeof(Graph)); 17 | graph->adjList = init_hashmap(); 18 | 19 | return graph; 20 | } 21 | 22 | void addEdgeDirectional(Graph*graph, char* from, char* to, double weight) { 23 | Vertex* new_vertex = init_vertex(to, weight); 24 | 25 | new_vertex->next = (Vertex*)get(graph->adjList, from); 26 | set(graph->adjList, from, new_vertex); 27 | } 28 | 29 | void addEdge(Graph* graph, char* from, char* to, double weight) { 30 | addEdgeDirectional(graph, from, to, weight); 31 | addEdgeDirectional(graph, to, from, weight); 32 | } 33 | 34 | void printGraph(Graph *graph) { 35 | for (int j = 0; j < HASHMAP_SIZE; j++) { 36 | EntryNode* entry = graph->adjList->entries[j]; 37 | 38 | while(entry != NULL) { 39 | Vertex* it = (Vertex*)entry->val; 40 | printf("Neighbors of %s: ", entry->key); 41 | while (it != NULL) 42 | { 43 | printf("%s ", it->val); 44 | it = it->next; 45 | } 46 | printf("\n"); 47 | 48 | entry = entry->next; 49 | } 50 | 51 | } 52 | } -------------------------------------------------------------------------------- /2024-2025/10a/2025-02-12-graphs/graphMatrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct Graph { 5 | int numVertices; 6 | int **adjMatrix; 7 | } Graph; 8 | 9 | Graph* init_graph(int numVertices) { 10 | Graph *graph = (Graph*)malloc(sizeof(Graph)); 11 | graph->numVertices = numVertices; 12 | graph->adjMatrix = (int**)malloc(numVertices * sizeof(int*)); 13 | for (int i = 0; i < numVertices; i++) { 14 | graph->adjMatrix[i] = (int*)calloc(numVertices, sizeof(int)); 15 | } 16 | 17 | return graph; 18 | } 19 | 20 | void addEdgeDirectional(Graph*graph, int from, int to) { 21 | graph->adjMatrix[from][to] = 1; 22 | } 23 | 24 | void addEdge(Graph* graph, int from, int to) { 25 | addEdgeDirectional(graph, from, to); 26 | addEdgeDirectional(graph, to, from); 27 | } 28 | 29 | void printGraph(Graph *graph) { 30 | printf("# "); 31 | for(int i = 0; i < graph->numVertices; i++) { 32 | printf("%d ", i); 33 | } 34 | printf("\n"); 35 | for (int i = 0; i < graph->numVertices; i++) { 36 | printf("%d ", i); 37 | for(int j = 0; j < graph->numVertices; j++) { 38 | printf("%d ", graph->adjMatrix[i][j]); 39 | } 40 | printf("\n"); 41 | } 42 | } 43 | 44 | int main() { 45 | Graph* g = init_graph(5); 46 | addEdgeDirectional(g,0,1); 47 | addEdge(g,0,2); 48 | addEdge(g,0,4); 49 | addEdge(g,3,4); 50 | addEdge(g,2,1); 51 | addEdge(g,2,3); 52 | 53 | printGraph(g); 54 | 55 | return 0; 56 | } -------------------------------------------------------------------------------- /2024-2025/10v/2024_12_11 heap/vector.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"vector.h" 4 | 5 | vector* init_vector(int initialCapacity) { 6 | vector* v = (vector*)malloc(sizeof(vector)); 7 | v->arr = (int*)malloc(sizeof(int) * initialCapacity); 8 | v->size = 0; 9 | v->capacity = initialCapacity; 10 | return v; 11 | } 12 | 13 | void push(vector* v, int val) { 14 | if(v->size >= v->capacity) { 15 | v->capacity *= 2; 16 | int* tmp = (int*)realloc(v->arr, sizeof(int) * v->capacity); 17 | if(tmp == NULL) { 18 | exit(0); 19 | } 20 | v->arr = tmp; 21 | } 22 | v->arr[v->size] = val; 23 | v->size++; 24 | } 25 | 26 | int pop(vector* v) { 27 | if(v->size == 0) { 28 | printf("Can't pop from empty vector\n"); 29 | exit(1); 30 | } 31 | int tmp = v->arr[v->size - 1]; 32 | v->size--; 33 | return tmp; 34 | } 35 | 36 | int getAt(vector *v, int i) { 37 | if (i >= v->size || i < 0) { 38 | printf("Invalid index for getAt\n"); 39 | exit(1); 40 | } 41 | return v->arr[i]; 42 | } 43 | 44 | void clear_vector(vector* v) { 45 | v->size = 0; 46 | free(v->arr); 47 | v->capacity = 2; 48 | v->arr = (int*) malloc(v->capacity*sizeof(int)); 49 | } 50 | 51 | void free_vector(vector* v) { 52 | free(v->arr); 53 | free(v); 54 | } 55 | 56 | void print_vector(vector* v) { 57 | for(int i = 0; i < v->size; i++) { 58 | printf("%d ", v->arr[i]); 59 | } 60 | printf("\n"); 61 | } -------------------------------------------------------------------------------- /2025-2026/10a/utils/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "queue.h" 4 | 5 | Node *create_node(int val) 6 | { 7 | Node *node = (Node *)malloc(sizeof(Node)); 8 | node->val = val; 9 | node->next = NULL; 10 | 11 | return node; 12 | } 13 | 14 | Queue *init_queue() 15 | { 16 | Queue *queue = (Queue *)malloc(sizeof(Queue)); 17 | queue->front = NULL; 18 | queue->rear = NULL; 19 | 20 | return queue; 21 | } 22 | 23 | void enqueue(Queue *queue, int val) 24 | { 25 | Node* new_node = create_node(val); 26 | if (queue->rear == NULL) { 27 | queue->front = new_node; 28 | } else { 29 | queue->rear->next = new_node; 30 | } 31 | queue->rear = new_node; 32 | } 33 | 34 | int dequeue(Queue *queue) 35 | { 36 | if (queue->front == NULL) { 37 | printf("Empty queue\n"); 38 | exit(1); 39 | } 40 | 41 | Node* front = queue->front; 42 | int res = front->val; 43 | 44 | queue->front = queue->front->next; 45 | 46 | if(queue->front == NULL) { 47 | queue->rear = NULL; 48 | } 49 | 50 | free(front); 51 | return res; 52 | } 53 | 54 | void clear_queue(Queue *queue) 55 | { 56 | while (queue->front != NULL) 57 | { 58 | dequeue(queue); 59 | } 60 | 61 | free(queue); 62 | } 63 | 64 | void print_queue(Queue *queue) 65 | { 66 | Node *it = queue->front; 67 | printf("Q: "); 68 | while (it != NULL) 69 | { 70 | printf("%d -> ", it->val); 71 | it = it->next; 72 | } 73 | printf("NULL\n"); 74 | } -------------------------------------------------------------------------------- /2025-2026/10b/2025-10-06-mergesort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void mergesort(int arr[], int size) { 4 | printf("mergesort with arr=%p and size=%d\n", arr, size); 5 | if(size < 2) { 6 | printf("base case reached with size=%d\n", size); 7 | return; 8 | } 9 | 10 | int mid = size / 2; 11 | printf("mid=%d\n", mid); 12 | mergesort(arr, mid); 13 | mergesort(arr + mid, size - mid); 14 | // arr[mid] === *(arr + mid) 15 | int temp[size]; 16 | int left = 0, right = mid, k = 0; 17 | 18 | while(left < mid && right < size) { 19 | printf("comparing arr[%d]=%d and arr[%d]=%d\n", left, arr[left], right, arr[right]); 20 | if(arr[left] < arr[right]) { 21 | temp[k++] = arr[left++]; 22 | } else { 23 | temp[k++] = arr[right++]; 24 | } 25 | } 26 | printf("left=%d, right=%d, k=%d\n", left, right, k); 27 | while(left < mid) { 28 | printf("copying arr[%d]=%d to temp[%d]\n", left, arr[left], k); 29 | temp[k++] = arr[left++]; 30 | } 31 | while(right < size) { 32 | printf("copying arr[%d]=%d to temp[%d]\n", right, arr[right], k); 33 | temp[k++] = arr[right++]; 34 | } 35 | 36 | for(int i = 0; i < k; i++) { 37 | arr[i] = temp[i]; 38 | } 39 | 40 | printf("merged array with size=%d\n", size); 41 | } 42 | 43 | int main() { 44 | int arr[] = {5, 3, 8, 6, 2, 7, 4, 1}; 45 | int size = sizeof(arr) / sizeof(arr[0]); 46 | mergesort(arr, size); 47 | for(int i = 0; i < size; i++) { 48 | printf("%d ", arr[i]); 49 | } 50 | printf("\n"); 51 | return 0; 52 | } -------------------------------------------------------------------------------- /2024-2025/10a/utils/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "queue.h" 4 | 5 | QNode *create_qnode(int val) 6 | { 7 | QNode *node = (QNode *)malloc(sizeof(QNode)); 8 | node->val = val; 9 | node->next = NULL; 10 | 11 | return node; 12 | } 13 | 14 | Queue *init_queue() 15 | { 16 | Queue *queue = (Queue *)malloc(sizeof(Queue)); 17 | queue->front = NULL; 18 | queue->rear = NULL; 19 | } 20 | 21 | void enqueue(Queue *queue, int val) 22 | { 23 | QNode *node = create_qnode(val); 24 | if (queue->front == NULL) 25 | { 26 | queue->rear = queue->front = node; 27 | return; 28 | } 29 | 30 | queue->rear->next = node; 31 | queue->rear = node; 32 | } 33 | 34 | int dequeue(Queue *queue) 35 | { 36 | if (queue->front == NULL) 37 | { 38 | printf("Queue is empty.\n"); 39 | exit(1); 40 | } 41 | 42 | QNode *front = queue->front; 43 | 44 | int val = front->val; 45 | QNode *tmp = front; 46 | queue->front = front->next; 47 | free(tmp); 48 | 49 | if (queue->front == NULL) 50 | { 51 | queue->rear = NULL; 52 | } 53 | 54 | return val; 55 | } 56 | 57 | void clear_queue(Queue *queue) 58 | { 59 | while (queue->front != NULL) 60 | { 61 | dequeue(queue); 62 | } 63 | 64 | free(queue); 65 | } 66 | void print_queue(Queue *queue) 67 | { 68 | QNode *it = queue->front; 69 | printf("Q: "); 70 | while (it != NULL) 71 | { 72 | printf("%d -> ", it->val); 73 | it = it->next; 74 | } 75 | printf("NULL\n"); 76 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-01-04-exam-2-solution/main.c: -------------------------------------------------------------------------------- 1 | struct tree_node_t { 2 | struct tree_node_t* left; 3 | struct tree_node_t* right; 4 | struct tree_node_t* parent; 5 | 6 | char dir; 7 | int x; 8 | int y; 9 | }; 10 | 11 | struct tree_node_t* init_node(char d, int x, int y, struct tree_node_t* parent) { 12 | struct tree_node_t* new_node = malloc(sizeof(struct tree_node_t)); 13 | new_node->left = new_node->right = NULL; 14 | 15 | new_node->parent = parent; 16 | new_node->dir = d; 17 | new_node->x = x; 18 | new_node->y = y; 19 | 20 | return new_node; 21 | } 22 | 23 | // ═ 24 | // in left -> out right: (x + 1, y), S 25 | // in right -> out left: (x - 1, y), S 26 | // 0001 -> +1, 0, S 27 | // 0010 -> -1, 0, S 28 | // ╝ 29 | // in left -> out top: ( x, y - 1), L 30 | // in top -> out left: (x - 1, y), R 31 | // 0001 -> 0, -1, L 32 | // 0100 -> -1, 0, R 33 | 34 | ═ 35 | [ 36 | [1, 0, 'S'], 37 | [-1, 0, 'S'], 38 | [], 39 | [] 40 | ] 41 | ╝ 42 | [ 43 | [0, -1, 'L'], 44 | [], 45 | [-1, 0, 'R'], 46 | [] 47 | ] 48 | 49 | char* help_santa(char* maze, int start_x, int start_y) { 50 | struct tree_node_t* root = init_node('-', start_x, start_y, NULL); 51 | 52 | root->left = init_node('L', start_x - 1, start_y, root); 53 | root->right = init_node('R', start_x + 1, start_y, root); 54 | 55 | struct tree_node_t* curr = root->left; 56 | char cell = maze[curr->y][curr->x]; 57 | 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /2023-2024/10a/utils/graph.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "graph.h" 5 | 6 | VertexNode *init_node(int val, int weigth) 7 | { 8 | VertexNode *node = (VertexNode *)malloc(sizeof(VertexNode)); 9 | node->val = val; 10 | node->next = NULL; 11 | node->weight = weigth; 12 | 13 | return node; 14 | } 15 | 16 | Graph *init_graph(int numVertices) 17 | { 18 | Graph *graph = (Graph *)malloc(sizeof(Graph)); 19 | graph->numVertices = numVertices; 20 | graph->adjList = (VertexNode **)calloc(numVertices, sizeof(VertexNode *)); 21 | 22 | return graph; 23 | } 24 | 25 | void addEdgeDirectional(Graph *graph, int from, int to, int weight) 26 | { 27 | if (from < 0 || from >= graph->numVertices || to < 0 || to >= graph->numVertices) 28 | { 29 | printf("Invalid from or to\n"); 30 | return; 31 | } 32 | 33 | VertexNode *newNode = init_node(to, weight); 34 | 35 | newNode->next = graph->adjList[from]; 36 | graph->adjList[from] = newNode; 37 | } 38 | 39 | void addEdge(Graph *graph, int from, int to, int weight) 40 | { 41 | addEdgeDirectional(graph, from, to, weight); 42 | addEdgeDirectional(graph, to, from, weight); 43 | } 44 | 45 | void printGraph(Graph *graph) 46 | { 47 | for (int i = 0; i < graph->numVertices; i++) 48 | { 49 | VertexNode *current = graph->adjList[i]; 50 | printf("Neighbours of %d:\n", i); 51 | while (current != NULL) 52 | { 53 | printf("%d ", current->val); 54 | current = current->next; 55 | } 56 | printf("\n"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /2023-2024/10a/2024-04-09-hash-map-tasks/main.c: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/ransom-note/?envType=study-plan-v2&envId=top-interview-150 2 | 3 | bool canConstruct(char *ransomNote, char *magazine) 4 | { 5 | int letterOccurences[26] = {0}; 6 | 7 | for (int i = 0; ransomNote[i] != '\0'; i++) 8 | { 9 | char key = ransomNote[i]; 10 | letterOccurences[key - 'a']++; 11 | } 12 | 13 | for (int i = 0; magazine[i] != '\0'; i++) 14 | { 15 | letterOccurences[magazine[i] - 'a']--; 16 | } 17 | 18 | for (int i = 0; i < 26; i++) 19 | { 20 | if (letterOccurences[i] > 0) 21 | { 22 | return false; 23 | } 24 | } 25 | 26 | return true; 27 | } 28 | 29 | // https://leetcode.com/problems/isomorphic-strings/?envType=study-plan-v2&envId=top-interview-150 30 | 31 | class Solution 32 | { 33 | public: 34 | bool isIsomorphic(string s, string t) 35 | { 36 | unordered_map char_map; 37 | unordered_map char_map2; 38 | 39 | /* 40 | { 41 | b: b, 42 | a: a, 43 | } 44 | */ 45 | 46 | for (int i = 0; s[i] != '\0'; i++) 47 | { 48 | if (char_map[s[i]] && char_map[s[i]] != t[i]) 49 | { 50 | return false; 51 | } 52 | if (char_map2[t[i]] && char_map2[t[i]] != s[i]) 53 | { 54 | return false; 55 | } 56 | 57 | char_map[s[i]] = t[i]; 58 | char_map2[t[i]] = s[i]; 59 | } 60 | 61 | return true; 62 | } 63 | }; -------------------------------------------------------------------------------- /2024-2025/10v/2025_02_25 graph traversal/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "queue.h" 4 | 5 | QNode* createQnode(int val) { 6 | QNode* node = (QNode* )malloc(sizeof(QNode)); 7 | node->val = val; 8 | node->next = NULL; 9 | 10 | return node; 11 | } 12 | 13 | Queue* initQueue() { 14 | Queue* queue = (Queue* )malloc(sizeof(Queue)); 15 | queue->front = NULL; 16 | queue->rear = NULL; 17 | } 18 | 19 | int isEmpty(Queue* queue) { 20 | if(queue->front) { 21 | return 1; 22 | } 23 | return 0; 24 | } 25 | 26 | void push(Queue* queue, int val) { 27 | QNode* node = createQnode(val); 28 | if (queue->front == NULL) { 29 | queue->rear = queue->front = node; 30 | return; 31 | } 32 | 33 | queue->rear->next = node; 34 | queue->rear = node; 35 | } 36 | 37 | int pop(Queue* queue) { 38 | if (!queue->front) { 39 | printf("Queue is empty.\n"); 40 | exit(1); 41 | } 42 | 43 | QNode* front = queue->front; 44 | 45 | int val = front->val; 46 | QNode* tmp = front; 47 | queue->front = front->next; 48 | free(tmp); 49 | 50 | if (queue->front == NULL) { 51 | queue->rear = NULL; 52 | } 53 | 54 | return val; 55 | } 56 | 57 | void clearQueue(Queue* queue) { 58 | while (queue->front != NULL) { 59 | pop(queue); 60 | } 61 | 62 | free(queue); 63 | } 64 | 65 | void printQueue(Queue* queue) { 66 | QNode* it = queue->front; 67 | printf("Q: "); 68 | while (it != NULL) { 69 | printf("%d -> ", it->val); 70 | it = it->next; 71 | } 72 | printf("NULL\n"); 73 | } -------------------------------------------------------------------------------- /2024-2025/10v/2024_09_20 C revision/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int* a, int* b) { 4 | int tmp = *a; 5 | *a = *b; 6 | *b = tmp; 7 | } 8 | 9 | void swapNoTMP(int* a, int* b) { 10 | // без този if ако подадем 2 указателя към една и съща памет ще се занулят 11 | if(a != b) { 12 | *a = *a ^ *b; 13 | *b = *a ^ *b; 14 | *a = *a ^ *b; 15 | } 16 | } 17 | 18 | int sumOneToN(int n) { 19 | int res = 0; 20 | for(int i = 1; i <= n; i++) { 21 | res += i; 22 | } 23 | return res; 24 | } 25 | 26 | int sumOneToNRec(int n) { 27 | if(n < 1){ 28 | return 0; 29 | } 30 | return n + sumOneToNRec(n-1); 31 | } 32 | 33 | int linearSearch(int arr[], int size, int item) { 34 | for(int i = 0; i < size; i++) { 35 | if( arr[i] == item) { 36 | return i; 37 | } 38 | } 39 | return -1; 40 | } 41 | 42 | int binarySearch(int arr[], int size, int item) { 43 | int left = 0; 44 | int right = size-1; 45 | while(left<=right) { 46 | int middle = left + (right - left)/2; 47 | if(item == arr[middle]) { 48 | return middle; 49 | } 50 | if(item < arr[middle]){ 51 | right = middle-1; 52 | } 53 | else { 54 | left = middle+1; 55 | } 56 | } 57 | return -1; 58 | } 59 | 60 | typedef struct Point { 61 | double x; 62 | double y; 63 | } Point; 64 | 65 | double dist(Point p1, Point p2) { 66 | double dx = p1.x - p2.x; 67 | double dy = p1.y - p2.y; 68 | return sqrt(dx * dx + dy * dy); 69 | } 70 | 71 | int main() 72 | 73 | { 74 | } -------------------------------------------------------------------------------- /2023-2024/10a/2023-12-06-heap/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../utils/vector.h" 3 | 4 | void swap(int *a, int *b) 5 | { 6 | int temp = *a; 7 | *a = *b; 8 | *b = temp; 9 | } 10 | 11 | void siftDown(vector_t *v, int i, int size) 12 | { 13 | int swapped = 1; 14 | 15 | while (swapped) 16 | { 17 | swapped = 0; 18 | int largest = i; 19 | int left = 2 * i + 1; 20 | int right = 2 * i + 2; 21 | 22 | if (left < size && v->arr[left] > v->arr[largest]) 23 | { 24 | largest = left; 25 | } 26 | if (right < size && v->arr[right] > v->arr[largest]) 27 | { 28 | largest = right; 29 | } 30 | 31 | if (i != largest) 32 | { 33 | swap(&v->arr[i], &v->arr[largest]); 34 | i = largest; 35 | swapped = 1; 36 | } 37 | } 38 | } 39 | 40 | void heapify(vector_t *v) 41 | { 42 | for (int i = v->size / 2; i >= 0; i--) 43 | { 44 | siftDown(v, i, v->size); 45 | } 46 | } 47 | 48 | void heapsort(vector_t *v) 49 | { 50 | heapify(v); 51 | 52 | for (int i = 0; i < v->size; i++) 53 | { 54 | swap(&v->arr[0], &v->arr[v->size - 1 - i]); 55 | siftDown(v, 0, v->size - i - 1); 56 | } 57 | } 58 | 59 | int main() 60 | { 61 | vector_t *v = init_vector(); 62 | push_back(v, 20); 63 | push_back(v, 50); 64 | push_back(v, 15); 65 | push_back(v, 8); 66 | push_back(v, 26); 67 | push_back(v, 10); 68 | push_back(v, 16); 69 | push_back(v, 30); 70 | 71 | printVector(v); 72 | heapsort(v); 73 | printVector(v); 74 | 75 | return 0; 76 | } -------------------------------------------------------------------------------- /2025-2026/10a/2025-10-27-mergesort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void merge(int* arr, int left, int mid, int right) { 5 | int size = right - left + 1; 6 | int *temp = (int*)malloc(size*sizeof(int)); 7 | int i = left; 8 | int j = mid + 1; 9 | int k = 0; 10 | 11 | // n 12 | while (i <= mid && j <= right) { 13 | if (arr[i] < arr[j]) { 14 | temp[k] = arr[i]; 15 | i++; 16 | k++; 17 | } else { 18 | temp[k] = arr[j]; 19 | j++; 20 | k++; 21 | } 22 | } 23 | 24 | while (i <= mid) { 25 | temp[k] = arr[i]; 26 | i++; 27 | k++; 28 | } 29 | 30 | while (j <= right) { 31 | temp[k] = arr[j]; 32 | j++; 33 | k++; 34 | } 35 | 36 | // n 37 | for (int h = 0; h < size; h++) { 38 | arr[left + h] = temp[h]; 39 | } 40 | 41 | free(temp); 42 | } 43 | 44 | void MergeSort(int *arr, int left, int right) { 45 | if (left >= right) { 46 | return; 47 | } 48 | int mid = (left + right) / 2; 49 | 50 | MergeSort(arr, left, mid); 51 | MergeSort(arr, mid + 1, right); 52 | 53 | 54 | printf("%d %d %d\n", left, right, mid); 55 | for(int i = 0; i < 8;i++) { 56 | printf("%d ", arr[i]); 57 | } 58 | printf("\n"); 59 | merge(arr, left, mid, right); 60 | for(int i = 0; i < 8;i++) { 61 | printf("%d ", arr[i]); 62 | } 63 | printf("\n"); 64 | } 65 | 66 | int main() { 67 | int arr[] = {10, 5, 7, 1, 30, 100, 25, 37}; 68 | MergeSort(arr, 0, 7); 69 | 70 | for(int i = 0; i < 8;i++) { 71 | printf("%d ", arr[i]); 72 | } 73 | printf("\n"); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /2024-2025/10v/2024_12_11 heap/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"vector.h" 4 | 5 | void swap(int* a, int* b) { 6 | int tmp = *a; 7 | *a = *b; 8 | *b = tmp; 9 | } 10 | 11 | void siftUp(vector* v, int i) { 12 | if(i <= 0) { 13 | return; 14 | } 15 | int parent = (i - 1) / 2; 16 | if (v->arr[parent] < v->arr[i]) { 17 | swap(&v->arr[parent], &v->arr[i]); 18 | siftUp(v, parent); 19 | } 20 | } 21 | 22 | void siftDown(vector* v, int i) { 23 | int left = 2*i + 1; 24 | int right = 2*i + 2; 25 | int maxIndex; 26 | 27 | if (left >= v->size) { 28 | return; 29 | } 30 | 31 | 32 | 33 | if (right < v->size && v->arr[right] > v->arr[left]) { 34 | maxIndex = right; 35 | } else { 36 | maxIndex = left; 37 | } 38 | 39 | if (v->arr[i] < v->arr[maxIndex]) { 40 | swap(&v->arr[i], &v->arr[maxIndex]); 41 | siftDown(v, maxIndex); 42 | } 43 | } 44 | 45 | int heap_pop(vector* v) { 46 | if(!v->size) { 47 | printf("Can't pop empty heap"); 48 | exit(1); 49 | } 50 | int val = v->arr[0]; 51 | v->arr[0] = pop(v); 52 | siftDown(v, 0); 53 | return val; 54 | } 55 | 56 | void heap_insert(vector* v, int val) { 57 | push(v, val); 58 | siftUp(v, v->size-1); 59 | } 60 | 61 | int main() { 62 | vector* v = init_vector(8); 63 | heap_insert(v, 1); 64 | heap_insert(v, 3); 65 | heap_insert(v, 8); 66 | heap_insert(v, 6); 67 | heap_insert(v, 3); 68 | heap_insert(v, 7); 69 | heap_insert(v, 10); 70 | heap_insert(v, 1); 71 | 72 | while (v->size){ 73 | printf("%d ", heap_pop(v)); 74 | } 75 | } -------------------------------------------------------------------------------- /2024-2025/10a/2025-02-12-graphs/graph.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct Vertex { 5 | int val; 6 | struct Vertex* next; 7 | } Vertex; 8 | 9 | typedef struct Graph { 10 | int numVertices; 11 | Vertex **adjList; 12 | } Graph; 13 | 14 | Vertex* init_vertex(int val) { 15 | Vertex* vertex = (Vertex*)malloc(sizeof(Vertex)); 16 | vertex->val = val; 17 | vertex->next = NULL; 18 | 19 | return vertex; 20 | } 21 | 22 | Graph* init_graph(int numVertices) { 23 | Graph *graph = (Graph*)malloc(sizeof(Graph)); 24 | graph->numVertices = numVertices; 25 | graph->adjList = (Vertex**)calloc(numVertices, sizeof(Vertex*)); 26 | 27 | return graph; 28 | } 29 | 30 | void addEdgeDirectional(Graph*graph, int from, int to) { 31 | Vertex* new_vertex = init_vertex(to); 32 | new_vertex->next = graph->adjList[from]; 33 | graph->adjList[from] = new_vertex; 34 | } 35 | 36 | void addEdge(Graph* graph, int from, int to) { 37 | addEdgeDirectional(graph, from, to); 38 | addEdgeDirectional(graph, to, from); 39 | } 40 | 41 | void printGraph(Graph *graph) { 42 | for (int i = 0; i < graph->numVertices; i++) { 43 | Vertex* it = graph->adjList[i]; 44 | printf("Neighbors of %d: ", i); 45 | while (it != NULL) 46 | { 47 | printf("%d ", it->val); 48 | it = it->next; 49 | } 50 | printf("\n"); 51 | } 52 | } 53 | 54 | int main() { 55 | Graph* g = init_graph(5); 56 | addEdgeDirectional(g,0,1); 57 | addEdge(g,0,2); 58 | addEdge(g,0,4); 59 | addEdge(g,3,4); 60 | addEdge(g,2,1); 61 | addEdge(g,2,3); 62 | 63 | printGraph(g); 64 | 65 | return 0; 66 | } -------------------------------------------------------------------------------- /2024-2025/10b/2024-10-28-set/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct set_t { 5 | int size; 6 | int *data; 7 | }; 8 | typedef struct set_t set_t; 9 | 10 | set_t* init_set() { 11 | set_t *set = malloc(sizeof(set_t)); 12 | set->size = 0; 13 | set->data = NULL; 14 | return set; 15 | } 16 | 17 | int set_contains(set_t *set, int value) { 18 | for(int i = 0; i < set->size; i++) 19 | if(set->data[i] == value) 20 | return 1; 21 | return 0; 22 | } 23 | 24 | void add(set_t *set, int value) { 25 | // for(int i = 0; i < set->size; i++) 26 | // if(set->data[i] == value) 27 | // return; 28 | if(set_contains(set, value)) 29 | return; 30 | 31 | set->size++; 32 | // set->size *= 2; 33 | set->data = realloc(set->data, set->size * sizeof(int)); 34 | set->data[set->size - 1] = value; 35 | } 36 | 37 | int is_subset(set_t *big, set_t *small) { 38 | for(int i = 0; i < small->size; i++) 39 | if(!set_contains(big, small->data[i])) 40 | return 0; 41 | 42 | return 1; 43 | } 44 | 45 | void print_set(set_t *set) { 46 | for(int i = 0; i < set->size; i++) 47 | printf("%d ", set->data[i]); 48 | printf("\n"); 49 | } 50 | 51 | int main() { 52 | set_t *set1 = init_set(); 53 | add(set1, 1); 54 | add(set1, 2); 55 | add(set1, 3); 56 | 57 | set_t *set2 = init_set(); 58 | add(set2, 4); 59 | add(set2, 2); 60 | 61 | printf("%d\n", set1->size); 62 | print_set(set1); 63 | printf("%d\n", set2->size); 64 | print_set(set2); 65 | 66 | printf("%d %d\n", set_contains(set1, 3), set_contains(set1, 4)); 67 | printf("%d\n", is_subset(set1, set2)); 68 | return 0; 69 | } -------------------------------------------------------------------------------- /2024-2025/10v/2025_02_18 graphs/adjMatrixGraph.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct Graph { 5 | int vertexCount; 6 | int** adjMatrix; 7 | } Graph; 8 | 9 | Graph* initGraph(int vertexCount) { 10 | Graph* graph = (Graph*) malloc(sizeof(Graph)); 11 | graph->vertexCount = vertexCount; 12 | graph->adjMatrix = (int**) malloc(sizeof(int*) * vertexCount); 13 | 14 | for(int i = 0; i < vertexCount; i++) { 15 | graph->adjMatrix[i] = (int*) calloc(vertexCount, sizeof(int)); 16 | } 17 | 18 | return graph; 19 | } 20 | 21 | void printGraph(Graph* graph) { 22 | printf("# "); 23 | for(int i = 0; i < graph->vertexCount; i++) { 24 | printf("%d ", i); 25 | } 26 | printf("\n"); 27 | for(int i = 0; i < graph->vertexCount; i++) { 28 | printf("%d ", i); 29 | for(int j = 0; j < graph->vertexCount; j++) { 30 | printf("%d ", graph->adjMatrix[i][j]); 31 | } 32 | printf("\n"); 33 | } 34 | } 35 | 36 | void addEdgeDirectional(Graph* graph, int from, int to) { 37 | graph->adjMatrix[from][to] = 1; 38 | } 39 | 40 | void addEdge(Graph* graph, int vertex1, int vertex2) { 41 | addEdgeDirectional(graph, vertex1, vertex2); 42 | addEdgeDirectional(graph, vertex2, vertex1); 43 | } 44 | 45 | int main() { 46 | Graph* graph = initGraph(6); 47 | addEdgeDirectional(graph, 0, 5); 48 | addEdgeDirectional(graph, 4, 0); 49 | addEdge(graph, 0, 3); 50 | addEdge(graph, 4, 3); 51 | addEdge(graph, 1, 5); 52 | addEdge(graph, 4, 1); 53 | addEdge(graph, 4, 2); 54 | addEdge(graph, 1, 2); 55 | addEdge(graph, 5, 2); 56 | addEdge(graph, 0, 1); 57 | 58 | printGraph(graph); 59 | } -------------------------------------------------------------------------------- /2025-2026/10a/utils/vector.c: -------------------------------------------------------------------------------- 1 | #include "vector.h" 2 | #include 3 | #include 4 | 5 | vector* init_vector() { 6 | vector* v = (vector*)malloc(sizeof(vector)); 7 | if (v == NULL) { 8 | exit(1); 9 | } 10 | 11 | v->capacity = 2; 12 | v->data = (int*)malloc(sizeof(int)*v->capacity); 13 | v->size = 0; 14 | 15 | return v; 16 | } 17 | 18 | void push(vector* v, int val) { 19 | if (v->size == v->capacity) { 20 | v->capacity *= 2; 21 | v->data = (int*)realloc(v->data, sizeof(int)*v->capacity); 22 | } 23 | v->data[v->size] = val; 24 | v->size++; 25 | } 26 | 27 | int pop(vector* v) { 28 | v->size--; 29 | 30 | if (v->size < v->capacity / 2) { 31 | v->capacity /= 2; 32 | v->data = (int*)realloc(v->data, sizeof(int)*v->capacity); 33 | } 34 | 35 | return v->data[v->size]; 36 | } 37 | 38 | void pushFront(vector* v, int val) { 39 | if (v->size == v->capacity) { 40 | v->capacity *= 2; 41 | v->data = (int*)realloc(v->data, sizeof(int)*v->capacity); 42 | } 43 | 44 | for (int i = v->size; i > 0; i--) { 45 | v->data[i] = v->data[i - 1]; 46 | } 47 | 48 | v->data[0] = val; 49 | v->size++; 50 | } 51 | 52 | int popFront(vector* v) { 53 | int res = v->data[0]; 54 | 55 | for (int i = 0; i < v->size - 1; i++) { 56 | v->data[i] = v->data[i + 1]; 57 | } 58 | v->size--; 59 | 60 | return res; 61 | } 62 | 63 | 64 | void print_vector(vector* v) { 65 | for (int i = 0; i < v->size; i++) { 66 | printf("%d ", v->data[i]); 67 | } 68 | printf("\n"); 69 | } 70 | 71 | void free_vector(vector* v) { 72 | free(v->data); 73 | free(v); 74 | } -------------------------------------------------------------------------------- /2025-2026/10a/2025-09-29-vector/vector.c: -------------------------------------------------------------------------------- 1 | #include "vector.h" 2 | #include 3 | #include 4 | 5 | vector* init_vector() { 6 | vector* v = (vector*)malloc(sizeof(vector)); 7 | if (v == NULL) { 8 | exit(1); 9 | } 10 | 11 | v->capacity = 2; 12 | v->data = (int*)malloc(sizeof(int)*v->capacity); 13 | v->size = 0; 14 | 15 | return v; 16 | } 17 | 18 | void push(vector* v, int val) { 19 | if (v->size == v->capacity) { 20 | v->capacity *= 2; 21 | v->data = (int*)realloc(v->data, sizeof(int)*v->capacity); 22 | } 23 | v->data[v->size] = val; 24 | v->size++; 25 | } 26 | 27 | int pop(vector* v) { 28 | v->size--; 29 | 30 | if (v->size < v->capacity / 2) { 31 | v->capacity /= 2; 32 | v->data = (int*)realloc(v->data, sizeof(int)*v->capacity); 33 | } 34 | 35 | return v->data[v->size]; 36 | } 37 | 38 | void pushFront(vector* v, int val) { 39 | if (v->size == v->capacity) { 40 | v->capacity *= 2; 41 | v->data = (int*)realloc(v->data, sizeof(int)*v->capacity); 42 | } 43 | 44 | for (int i = v->size; i > 0; i--) { 45 | v->data[i] = v->data[i - 1]; 46 | } 47 | 48 | v->data[0] = val; 49 | v->size++; 50 | } 51 | 52 | int popFront(vector* v) { 53 | int res = v->data[0]; 54 | 55 | for (int i = 0; i < v->size - 1; i++) { 56 | v->data[i] = v->data[i + 1]; 57 | } 58 | v->size--; 59 | 60 | return res; 61 | } 62 | 63 | 64 | void print_vector(vector* v) { 65 | for (int i = 0; i < v->size; i++) { 66 | printf("%d ", v->data[i]); 67 | } 68 | printf("\n"); 69 | } 70 | 71 | void free_vector(vector* v) { 72 | free(v->data); 73 | free(v); 74 | } -------------------------------------------------------------------------------- /2024-2025/10v/2024_11_27 avl/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "avlTree.h" 5 | 6 | struct Queue { 7 | void* top; 8 | struct Queue* next; 9 | }; 10 | typedef struct Queue Queue; 11 | 12 | Queue* createQueueNode(void* value) { 13 | Queue* new_node = malloc(sizeof(Queue)); 14 | new_node->top = value; 15 | new_node->next = NULL; 16 | 17 | return new_node; 18 | } 19 | 20 | Queue* queuePush(Queue* q, void* value) { 21 | Queue* newNode = createQueueNode(value); 22 | 23 | if(!q) { 24 | return newNode; 25 | } 26 | 27 | Queue* curr = q; 28 | while(curr->next) { 29 | curr = curr->next; 30 | } 31 | curr->next = newNode; 32 | 33 | return q; 34 | } 35 | 36 | void* queuePop(Queue** q) { 37 | if(!(*q)) { 38 | return NULL; 39 | } 40 | void* value = (*q)->top; 41 | 42 | Queue* temp = *q; 43 | (*q) = (*q)->next; 44 | free(temp); 45 | 46 | return value; 47 | } 48 | 49 | void printTreeBfs(AVLNode* root) { 50 | if (!root) { 51 | return; 52 | } 53 | 54 | Queue* q = createQueueNode(root); 55 | while(q) { 56 | AVLNode* curr = queuePop(&q); 57 | if(!curr) { 58 | continue; 59 | } 60 | 61 | printf("%d ", curr->val); 62 | q = queuePush(q, curr->left); 63 | q = queuePush(q, curr->right); 64 | } 65 | } 66 | 67 | 68 | int main() { 69 | AVLNode* root = createNode(12); 70 | root = insert(root, 8); 71 | root = insert(root, 5); 72 | root = insert(root, 4); 73 | root = insert(root, 11); 74 | root = insert(root, 18); 75 | root = insert(root, 17); 76 | 77 | // printInOrder(root); 78 | printTreeBfs(root); 79 | } -------------------------------------------------------------------------------- /2025-2026/10b/2025-09-25-intro/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct list_node_t { 5 | struct list_node_t *next; 6 | int value; 7 | }; 8 | 9 | typedef struct list_node_t list_node_t; 10 | 11 | list_node_t* create_node(int value) { 12 | list_node_t *node = malloc(sizeof(list_node_t)); 13 | node->next = NULL; 14 | node->value = value; 15 | return node; 16 | } 17 | 18 | void push_front(list_node_t **head, int value) { 19 | if(head == NULL) { 20 | return; 21 | } 22 | list_node_t *node = create_node(value); 23 | node->next = *head; 24 | *head = node; 25 | } 26 | // struct list_node_t * push_front(struct list_node_t *head, int value) 27 | 28 | void push_back(list_node_t **head, int value) { 29 | if(head == NULL) { 30 | return; 31 | } 32 | if(*head == NULL) { 33 | push_front(head, value); 34 | return; 35 | } 36 | list_node_t *node = create_node(value); 37 | list_node_t *cur = *head; 38 | while (cur->next != NULL) { 39 | cur = cur->next; 40 | } 41 | cur->next = node; 42 | } 43 | 44 | 45 | list_node_t* push_back_v2(list_node_t *head, int value) { 46 | if(head == NULL) { 47 | list_node_t *node = create_node(value); 48 | return node; 49 | } 50 | list_node_t *node = create_node(value); 51 | list_node_t *cur = head; 52 | while (cur->next != NULL) { 53 | cur = cur->next; 54 | } 55 | cur->next = node; 56 | return head; 57 | } 58 | 59 | 60 | int main() { 61 | // push_front(NULL, 42); 62 | // push_back(1234, 42); 63 | 64 | list_node_t *head = NULL; 65 | // push_front(&head, 42); 66 | push_back(&head, 42); 67 | 68 | printf("%d\n", head->value); 69 | return 0; 70 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-10-10-quicksort-2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int *a, int *b) { 4 | int c = *a; 5 | *a = *b; 6 | *b = c; 7 | } 8 | 9 | void quick_sort(int *arr, unsigned int size) { 10 | printf("Start: %p Size: %d End: %p\n", 11 | arr, size, arr + size - 1); 12 | 13 | // recursion condition 14 | if(size < 2) return; 15 | 16 | // choose pivot 17 | int pivot_index = size-1; // int is rounded down 18 | 19 | printf("Pivot at %d = %d\n", 20 | pivot_index, arr[pivot_index]); 21 | 22 | // rearrange around pivot 23 | for(int i = 0; i < pivot_index; i++) { 24 | printf("Compare [%d]%d ? [%d]%d\n", 25 | i, arr[i], pivot_index, arr[pivot_index]); 26 | if(arr[i] > arr[pivot_index]) { 27 | // move to the right 28 | printf("Swap [%d]%d with [%d]%d\n", 29 | i, arr[i], pivot_index, arr[pivot_index]); 30 | 31 | swap(arr + i, arr + pivot_index - 1); 32 | swap(arr + pivot_index-1, arr+pivot_index); 33 | pivot_index--; 34 | i--; 35 | for(int j = 0; j < size; j++) 36 | printf("[%d] %d ", j, arr[j]); 37 | puts(""); // printf("\n"); 38 | } 39 | } 40 | 41 | puts(""); 42 | // call recursively for left half and right half 43 | printf("Left sort\n"); 44 | quick_sort(arr, pivot_index); 45 | 46 | printf("Right sort\n"); 47 | quick_sort(arr + pivot_index + 1, size - pivot_index - 1); 48 | } 49 | 50 | int main() { 51 | int arr[] = {9, 3, 2, 7, 5, 1, 4, 8, 0, 6}; 52 | 53 | for(int i = 0; i < 10; i++) 54 | printf("[%d] %d ", i, arr[i]); 55 | puts(""); 56 | 57 | quick_sort(arr, 10); 58 | 59 | for(int i = 0; i < 10; i++) 60 | printf("[%d] %d ", i, arr[i]); 61 | puts(""); 62 | 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /2022-2023/10b/2022-10-12-bucketsort-exercise/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int *a, int *b) { 4 | int c = *a; 5 | *a = *b; 6 | *b = c; 7 | } 8 | 9 | void quick_sort(int *arr, unsigned int size) { 10 | printf("Start: %p Size: %d End: %p\n", 11 | arr, size, arr + size - 1); 12 | 13 | // recursion condition 14 | if(size < 2) return; 15 | 16 | // choose pivot 17 | int pivot_index = size-1; // int is rounded down 18 | 19 | printf("Pivot at %d = %d\n", 20 | pivot_index, arr[pivot_index]); 21 | 22 | // rearrange around pivot 23 | for(int i = 0; i < pivot_index; i++) { 24 | printf("Compare [%d]%d ? [%d]%d\n", 25 | i, arr[i], pivot_index, arr[pivot_index]); 26 | if(arr[i] > arr[pivot_index]) { 27 | // move to the right 28 | printf("Swap [%d]%d with [%d]%d\n", 29 | i, arr[i], pivot_index, arr[pivot_index]); 30 | 31 | swap(arr + i, arr + pivot_index - 1); 32 | swap(arr + pivot_index-1, arr+pivot_index); 33 | pivot_index--; 34 | i--; 35 | for(int j = 0; j < size; j++) 36 | printf("[%d] %d ", j, arr[j]); 37 | puts(""); // printf("\n"); 38 | } 39 | } 40 | 41 | puts(""); 42 | // call recursively for left half and right half 43 | printf("Left sort\n"); 44 | quick_sort(arr, pivot_index); 45 | 46 | printf("Right sort\n"); 47 | quick_sort(arr + pivot_index + 1, size - pivot_index - 1); 48 | } 49 | 50 | int main() { 51 | int arr[] = {9, 3, 2, 7, 5, 1, 4, 8, 0, 6}; 52 | 53 | for(int i = 0; i < 10; i++) 54 | printf("[%d] %d ", i, arr[i]); 55 | puts(""); 56 | 57 | quick_sort(arr, 10); 58 | 59 | for(int i = 0; i < 10; i++) 60 | printf("[%d] %d ", i, arr[i]); 61 | puts(""); 62 | 63 | return 0; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /2023-2024/10a/2024-02-14-graphs/graph_matrix.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef struct Graph 5 | { 6 | int numVertices; 7 | int **adjMatrix; 8 | } Graph; 9 | 10 | Graph *init_graph(int numVertices) 11 | { 12 | Graph *graph = (Graph *)malloc(sizeof(Graph)); 13 | graph->numVertices = numVertices; 14 | graph->adjMatrix = (int **)malloc(numVertices * sizeof(int *)); 15 | 16 | for (int i = 0; i < numVertices; i++) 17 | { 18 | graph->adjMatrix[i] = (int *)calloc(numVertices, sizeof(int)); 19 | } 20 | 21 | return graph; 22 | } 23 | 24 | void addEdgeDirectional(Graph *graph, int from, int to) 25 | { 26 | if (from < 0 || from >= graph->numVertices || to < 0 || to >= graph->numVertices) 27 | { 28 | printf("Invalid from or to\n"); 29 | return; 30 | } 31 | 32 | graph->adjMatrix[from][to] = 1; 33 | } 34 | 35 | void addEdge(Graph *graph, int from, int to) 36 | { 37 | addEdgeDirectional(graph, from, to); 38 | addEdgeDirectional(graph, to, from); 39 | } 40 | 41 | void printGraph(Graph *graph) 42 | { 43 | for (int i = 0; i < graph->numVertices; i++) 44 | { 45 | for (int j = 0; j < graph->numVertices; j++) 46 | { 47 | printf("%d ", graph->adjMatrix[i][j]); 48 | } 49 | printf("\n"); 50 | } 51 | } 52 | 53 | // Make graph with adj matrix 54 | // or 55 | // BFS or DFS 56 | 57 | int main() 58 | { 59 | Graph *graph = init_graph(4); 60 | addEdge(graph, 1, 2); 61 | addEdgeDirectional(graph, 2, 4); 62 | addEdgeDirectional(graph, 3, 4); 63 | addEdgeDirectional(graph, 2, 3); 64 | addEdgeDirectional(graph, 1, 3); 65 | addEdgeDirectional(graph, 1, 1); 66 | 67 | printGraph(graph); 68 | 69 | return 0; 70 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-01-26-exam-3/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node_t { 5 | char* name; 6 | vector* children; 7 | 8 | char var_name; 9 | char condition; 10 | int target_value; 11 | }; 12 | 13 | struct node_t* create_node() { 14 | struct node_t* new_node = malloc(sizeof(struct node_t)); 15 | new_node->children = init_vector(); 16 | 17 | // new_node->name = strtok(step, " "); 18 | new_node->name = NULL; 19 | new_node->var_name = 0; // == '\0' 20 | new_node->condition = 0; 21 | new_node->target_value = 0; 22 | 23 | return new_node; 24 | } 25 | 26 | void populate_node(char* step, struct node_t* node) { 27 | node->name = strtok(step, " "); 28 | 29 | struct node_t* new_child = create_node(); 30 | new_child->name = ???; 31 | vector_add(node->children, new_child); 32 | } 33 | 34 | struct node_t* find_node(char* name, struct node_t* root) { 35 | if(strcmp(root->name, name) == 0) return root; 36 | 37 | for(int i =0; i < root->children->size; i++) { 38 | struct node_t* found = find_node(name, root->children[i]) 39 | if(found != NULL) return found; 40 | } 41 | 42 | return NULL; 43 | } 44 | 45 | struct node_t* add_node(char* step, struct node_t* root) { 46 | if(root == NULL) { 47 | struct node_t* new_node = create_node(); 48 | populate_node(step, new_node); 49 | return new_node; 50 | } 51 | 52 | char* search_name = ???; 53 | struct node_t* curr = find_node(search_name, root); 54 | populate_node(step, curr); 55 | 56 | return root; 57 | } 58 | 59 | int main() { 60 | struct node_t* root = add_node("A x gt 5 B C", NULL); 61 | return 0; 62 | } -------------------------------------------------------------------------------- /2022-2023/10b/2022-11-30-bst/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct node_t { 5 | int value; 6 | struct node_t *left; 7 | struct node_t *right; 8 | }; 9 | 10 | struct node_t * create_node(int value) { 11 | struct node_t * new_node = malloc(sizeof(struct node_t)); 12 | new_node->value = value; 13 | new_node->left = new_node->right = NULL; 14 | 15 | return new_node; 16 | } 17 | 18 | void add(struct node_t *root, int value) { 19 | 20 | //if(root->value > value) { 21 | // add left 22 | // child = root->left; 23 | /*if(root->left == NULL) { 24 | root->left = create_node(value); 25 | return; 26 | } else { 27 | add(root->left, value); 28 | }*/ 29 | //} else if(root->value < value) { 30 | //if(root->value < value) { 31 | // add right 32 | // child = &root->right; 33 | /*if(root->right == NULL) { 34 | root->right = create_node(value); 35 | return; 36 | } else { 37 | add(root->right, value); 38 | }*/ 39 | // } 40 | 41 | struct node_t ** child = &root->left; 42 | 43 | if(root->value < value) 44 | child = &root->right; 45 | 46 | if(*child == NULL) 47 | *child = create_node(value); 48 | else 49 | add(*child, value); 50 | } 51 | 52 | void print_dfs(struct node_t* root, int level) { 53 | if(root == NULL) return; 54 | 55 | printf("[%d] %d\n", level, root->value); 56 | if(root->left != NULL) 57 | printf("L"); 58 | print_dfs(root->left, level + 1); 59 | if(root->right != NULL) 60 | printf("R"); 61 | print_dfs(root->right, level + 1); 62 | } 63 | 64 | int main() { 65 | struct node_t* root = create_node(10); 66 | add(root, 6); 67 | add(root, 16); 68 | add(root, 5); 69 | 70 | print_dfs(root, 0); 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /2023-2024/10a/2024-03-05-graphs3/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../utils/graph.h" 3 | #include 4 | #include 5 | 6 | bool dfs(Graph *g, int *colors, int start_vertex, int next_color) 7 | { 8 | VertexNode *it = g->adjList[start_vertex]; 9 | 10 | // printf("From %d\n", start_vertex); 11 | while (it != NULL) 12 | { 13 | printf("From %d, Looking at %d, has color %d, next %d\n", start_vertex, it->val, colors[it->val], next_color); 14 | if (colors[it->val] == 0) 15 | { 16 | colors[it->val] = next_color; 17 | if (!dfs(g, colors, it->val, next_color == 1 ? 2 : 1)) 18 | { 19 | return false; 20 | } 21 | } 22 | else if (colors[it->val] != next_color) 23 | { 24 | return false; 25 | } 26 | 27 | it = it->next; 28 | } 29 | 30 | return true; 31 | } 32 | 33 | bool can_be_two_colored(Graph *g) 34 | { 35 | int *colors = (int *)calloc(g->numVertices, sizeof(int)); 36 | 37 | for (int i = 0; i < g->numVertices; i++) 38 | { 39 | if (colors[i] == 0) 40 | { 41 | colors[i] = 1; 42 | if (!dfs(g, colors, 0, 2)) 43 | { 44 | return false; 45 | } 46 | } 47 | } 48 | 49 | return true; 50 | } 51 | 52 | int main() 53 | { 54 | Graph *g = init_graph(6); 55 | addEdge(g, 0, 1); 56 | addEdge(g, 0, 2); 57 | addEdge(g, 1, 3); 58 | addEdge(g, 2, 3); 59 | addEdge(g, 3, 4); 60 | addEdge(g, 4, 5); 61 | addEdge(g, 2, 4); 62 | 63 | if (can_be_two_colored(g)) 64 | { 65 | printf("Is possible\n"); 66 | } 67 | else 68 | { 69 | printf("Is not"); 70 | } 71 | 72 | return 0; 73 | } -------------------------------------------------------------------------------- /2023-2024/10b/2023-11-11-heap-sort/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(int* left, int* right) { 4 | int tmp = *left; 5 | *left = *right; 6 | *right = tmp; 7 | } 8 | 9 | void print_arr(int* arr, int count) { 10 | for(int i = 0; i < count; i++) { 11 | printf("arr[%d] = %d\n", i, arr[i]); 12 | } 13 | } 14 | 15 | void siftup(int* arr, int pos) { 16 | 17 | printf("Before swap(%d): \n", pos); 18 | print_arr(arr, 7); 19 | swap(arr, arr + pos); 20 | 21 | printf("After swap(%d): \n", pos); 22 | print_arr(arr, 7); 23 | 24 | int curr = 0; 25 | while(1) { 26 | int left = curr * 2 + 1; 27 | int right = curr * 2 + 2; 28 | printf("left=%d right=%d\n", left, right); 29 | 30 | if(left >= pos || right >= pos) return; 31 | 32 | if(arr[curr] < arr[left] && arr[left] > arr[right]) { 33 | swap(arr + curr, arr + left); 34 | curr = left; 35 | } else if(arr[curr] < arr[right]) { 36 | swap(arr + curr, arr + right); 37 | curr = right; 38 | } else { 39 | return; 40 | } 41 | } 42 | } 43 | 44 | void heapsort(int* arr, int count) { 45 | for(int i = count - 1; i > 0; i--) { 46 | printf("Before siftup(%d): \n", i); 47 | print_arr(arr, 7); 48 | 49 | siftup(arr, i); 50 | 51 | printf("After siftup(%d): \n", i); 52 | print_arr(arr, 7); 53 | } 54 | } 55 | 56 | int main() { 57 | int arr[] = {30, 16, 24, 8, 12, 18, 23}; 58 | 59 | puts("Before sort: "); 60 | print_arr(arr, 7); 61 | 62 | heapsort(arr, 7); 63 | 64 | puts("After sort: "); 65 | print_arr(arr, 7); 66 | 67 | return 0; 68 | } -------------------------------------------------------------------------------- /2024-2025/10b/2024-11-18-bst-1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct tree_node_t { 5 | int value; 6 | struct tree_node_t* left; 7 | struct tree_node_t* right; 8 | }; 9 | typedef struct tree_node_t tree_node_t; 10 | 11 | tree_node_t* init_set_node(int value) { 12 | tree_node_t *node = malloc(sizeof(tree_node_t)); 13 | node->left = node->right = NULL; 14 | node->value = value; 15 | return node; 16 | } 17 | 18 | tree_node_t* add(tree_node_t *root, int value) { 19 | if(root == NULL) { 20 | tree_node_t* new_node = init_set_node(value); 21 | return new_node; 22 | } 23 | 24 | if(root->value > value) { 25 | // left 26 | root->left = add(root->left, value); 27 | } else if (root->value < value) { 28 | // right 29 | root->right = add(root->right, value); 30 | } 31 | 32 | return root; 33 | } 34 | 35 | void print_tree(tree_node_t* root) { 36 | if(root == NULL) { 37 | return; 38 | } 39 | 40 | printf("%p %d %p %p\n", root, root->value, root->left, root->right); 41 | 42 | print_tree(root->left); 43 | printf("%d\n", root->value); 44 | print_tree(root->right); 45 | } 46 | 47 | int main() { 48 | tree_node_t *my_tree = NULL; 49 | my_tree = add(my_tree, 10); 50 | my_tree = add(my_tree, 6); 51 | my_tree = add(my_tree, 7); 52 | my_tree = add(my_tree, 3); 53 | my_tree = add(my_tree, 15); 54 | my_tree = add(my_tree, 13); 55 | my_tree = add(my_tree, 20); 56 | 57 | print_tree(my_tree); 58 | 59 | // printf("%d\n", set1->size); 60 | // print_set(set1); 61 | // printf("%d\n", set2->size); 62 | // print_set(set2); 63 | 64 | // printf("%d %d\n", set_contains(set1, 3), set_contains(set1, 4)); 65 | // printf("%d\n", is_subset(set1, set2)); 66 | return 0; 67 | } -------------------------------------------------------------------------------- /2024-2025/10a/2025-05-15-graph-hashmap-and-leet-tasks/evaluateDivision.c: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/evaluate-division/ 2 | // use graph with hashmap 3 | 4 | double evaluateDiv(Graph *g, char* start, char* end, HashMap* visited, double accum) { 5 | if (strcmp(start, end) == 0) { 6 | return accum; 7 | } 8 | if (get(visited, start) != NULL) { 9 | return -1; 10 | } 11 | set(visited, start, (void*)1); 12 | //printf("%s\n",start); 13 | 14 | Vertex* it = (Vertex*)get(g->adjList, start); 15 | while(it != NULL) { 16 | double res = evaluateDiv(g, it->val, end, visited, accum * it->weight); 17 | if (res != -1) { 18 | return res; 19 | } 20 | 21 | it = it->next; 22 | } 23 | 24 | return -1; 25 | } 26 | 27 | /** 28 | * Note:H The returned array must be malloced, assume caller calls free(). 29 | */ 30 | double* calcEquation(char*** equations, int equationsSize, int* equationsColSize, 31 | double* values, int valuesSize, 32 | char*** queries, int queriesSize, int* queriesColSize, 33 | int* returnSize) { 34 | Graph* g = init_graph(); 35 | 36 | for(int i = 0; i < equationsSize; i++) { 37 | addEdgeDirectional(g, equations[i][0], equations[i][1], values[i]); 38 | addEdgeDirectional(g, equations[i][1], equations[i][0], 1/values[i]); 39 | } 40 | 41 | double* res = (double*)malloc(sizeof(double)*queriesSize); 42 | *returnSize = queriesSize; 43 | 44 | for(int i = 0; i < queriesSize; i++) { 45 | HashMap* visited = init_hashmap(); 46 | if (get(g->adjList, queries[i][0]) == NULL || get(g->adjList, queries[i][1]) == NULL) { 47 | res[i] = -1; 48 | continue; 49 | } 50 | 51 | res[i] = evaluateDiv(g, queries[i][0], queries[i][1], visited, 1); 52 | } 53 | 54 | return res; 55 | } -------------------------------------------------------------------------------- /2024-2025/10a/2025-07-09-consultation/dsu.c: -------------------------------------------------------------------------------- 1 | typedef struct Set { 2 | struct Set* parent; 3 | int rank; 4 | int size; 5 | } Set; 6 | 7 | Set* init_set() { 8 | Set* set = (Set*)malloc(sizeof(Set)); 9 | set->parent = set; 10 | set->rank = 0; 11 | set->size = 1; 12 | 13 | return set; 14 | } 15 | 16 | Set* find(Set* set) { 17 | if(set == set->parent) { 18 | return set; 19 | } 20 | return find(set->parent); 21 | } 22 | 23 | int set_union(Set* set1, Set* set2) { 24 | Set* root1 = find(set1); 25 | Set* root2 = find(set2); 26 | 27 | if (root1 == root2) { 28 | return root1->size; 29 | } 30 | 31 | if (root1->rank < root2->rank) { 32 | root1->parent = root2; 33 | root2->size += root1->size; 34 | return root2->size; 35 | } else { 36 | root2->parent = root1; 37 | if(root2->rank == root1->rank) { 38 | root1->rank++; 39 | } 40 | 41 | root1->size += root2->size; 42 | return root1->size; 43 | } 44 | } 45 | 46 | 47 | bool equationsPossible(char** equations, int equationsSize) { 48 | Set** sets = (Set**)malloc(sizeof(Set*)*26); 49 | for (int i = 0; i < 26; i++) { 50 | sets[i] = init_set(); 51 | } 52 | 53 | for (int i = 0; i < equationsSize; i++) { 54 | if (equations[i][1] == '=') { 55 | set_union(sets[equations[i][0] - 'a'], sets[equations[i][3] - 'a']); 56 | } 57 | } 58 | 59 | for (int i = 0; i < equationsSize; i++) { 60 | if (equations[i][1] == '!') { 61 | Set* group1 = find(sets[equations[i][0] - 'a']); 62 | Set* group2 = find(sets[equations[i][3] - 'a']); 63 | 64 | if(group1 == group2) { 65 | return false; 66 | } 67 | } 68 | } 69 | 70 | return true; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-11-graph-3/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = NULL; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | list_t* push_list(list_t* list, void* value) { 15 | // List is empty - create new node and return it 16 | if(list == NULL) { 17 | list_t* new_head = init_list(); 18 | new_head->value = value; 19 | return new_head; 20 | } 21 | 22 | // End of the list - create new node and attach it 23 | if(list->next == NULL) { 24 | list->next = push_list(list->next, value); 25 | return list; 26 | } 27 | 28 | // Middle of the list - continue recursively to the end 29 | push_list(list->next, value); 30 | return list; 31 | } 32 | 33 | void* pop_list(list_t** list) { 34 | if(*list == NULL) { 35 | return NULL; 36 | } 37 | 38 | list_t* old_head = *list; 39 | 40 | void* result = (*list)->value; 41 | *list = (*list)->next; 42 | 43 | free(old_head); 44 | 45 | return result; 46 | } 47 | 48 | void* list_get_at( 49 | list_t* list, 50 | unsigned int index 51 | ) { 52 | int len = list_length(list); 53 | if(len < index) return NULL; 54 | 55 | list_t* curr = list; 56 | int i = 0; 57 | 58 | while(i < index) { 59 | curr = curr->next; 60 | i++; 61 | } 62 | 63 | return curr->value; 64 | } 65 | 66 | int list_length(list_t* list) { 67 | int count = 0; 68 | while(list != NULL) { 69 | count++; 70 | list = list->next; 71 | } 72 | 73 | return count; 74 | } 75 | 76 | void destroy_list(list_t* list) { 77 | while(list != NULL) { 78 | list_t* tmp = list; 79 | list = list->next; 80 | 81 | free(tmp); 82 | } 83 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-18-dijkstra-2/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = NULL; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | list_t* push_list(list_t* list, void* value) { 15 | // List is empty - create new node and return it 16 | if(list == NULL) { 17 | list_t* new_head = init_list(); 18 | new_head->value = value; 19 | return new_head; 20 | } 21 | 22 | // End of the list - create new node and attach it 23 | if(list->next == NULL) { 24 | list->next = push_list(list->next, value); 25 | return list; 26 | } 27 | 28 | // Middle of the list - continue recursively to the end 29 | push_list(list->next, value); 30 | return list; 31 | } 32 | 33 | void* pop_list(list_t** list) { 34 | if(*list == NULL) { 35 | return NULL; 36 | } 37 | 38 | list_t* old_head = *list; 39 | 40 | void* result = (*list)->value; 41 | *list = (*list)->next; 42 | 43 | free(old_head); 44 | 45 | return result; 46 | } 47 | 48 | void* list_get_at( 49 | list_t* list, 50 | unsigned int index 51 | ) { 52 | int len = list_length(list); 53 | if(len < index) return NULL; 54 | 55 | list_t* curr = list; 56 | int i = 0; 57 | 58 | while(i < index) { 59 | curr = curr->next; 60 | i++; 61 | } 62 | 63 | return curr->value; 64 | } 65 | 66 | int list_length(list_t* list) { 67 | int count = 0; 68 | while(list != NULL) { 69 | count++; 70 | list = list->next; 71 | } 72 | 73 | return count; 74 | } 75 | 76 | void destroy_list(list_t* list) { 77 | while(list != NULL) { 78 | list_t* tmp = list; 79 | list = list->next; 80 | 81 | free(tmp); 82 | } 83 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-15-hashmap/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = NULL; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | list_t* push_list(list_t* list, void* value) { 15 | // List is empty - create new node and return it 16 | if(list == NULL) { 17 | list_t* new_head = init_list(); 18 | new_head->value = value; 19 | return new_head; 20 | } 21 | 22 | // End of the list - create new node and attach it 23 | if(list->next == NULL) { 24 | list->next = push_list(list->next, value); 25 | return list; 26 | } 27 | 28 | // Middle of the list - continue recursively to the end 29 | push_list(list->next, value); 30 | return list; 31 | } 32 | 33 | void* pop_list(list_t** list) { 34 | if(*list == NULL) { 35 | return NULL; 36 | } 37 | 38 | list_t* old_head = *list; 39 | 40 | void* result = (*list)->value; 41 | *list = (*list)->next; 42 | 43 | free(old_head); 44 | 45 | return result; 46 | } 47 | 48 | void* list_get_at( 49 | list_t* list, 50 | unsigned int index 51 | ) { 52 | int len = list_length(list); 53 | if(len < index) return NULL; 54 | 55 | list_t* curr = list; 56 | int i = 0; 57 | 58 | while(i < index) { 59 | curr = curr->next; 60 | i++; 61 | } 62 | 63 | return curr->value; 64 | } 65 | 66 | int list_length(list_t* list) { 67 | int count = 0; 68 | while(list != NULL) { 69 | count++; 70 | list = list->next; 71 | } 72 | 73 | return count; 74 | } 75 | 76 | void destroy_list(list_t* list) { 77 | while(list != NULL) { 78 | list_t* tmp = list; 79 | list = list->next; 80 | 81 | free(tmp); 82 | } 83 | } -------------------------------------------------------------------------------- /2024-2025/10v/2024_10_18 SkipList/skiplist.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "skiplist.h" 4 | 5 | Node* createNode(int val) { 6 | Node* newNode = (Node*) malloc(sizeof(Node)); 7 | if(newNode == NULL) { 8 | printf("Couldn't allocate for new node\n"); 9 | exit(1); 10 | } 11 | for(int i = 0; i < MAX_LEVEL; i++) { 12 | newNode->next[i] = NULL; 13 | } 14 | newNode->val = val; 15 | return newNode; 16 | } 17 | 18 | SkipList init() { 19 | SkipList list = { 20 | .head = createNode(0), 21 | }; 22 | return list; 23 | } 24 | 25 | void insert(SkipList* list, int val) { 26 | Node* newNode = createNode(val); 27 | 28 | Node* curr[MAX_LEVEL] = {0}; 29 | curr[MAX_LEVEL-1] = list->head; 30 | for(int i = MAX_LEVEL - 1; i >= 0; i--) { 31 | while(curr[i]->next[i] != NULL && curr[i]->next[i]->val < val){ 32 | curr[i] = curr[i]->next[i]; 33 | } 34 | if(i > 0){ 35 | curr[i-1] = curr[i]; 36 | } 37 | } 38 | 39 | int level = 0; 40 | 41 | do { 42 | newNode->next[level] = curr[level]->next[level]; 43 | curr[level]->next[level] = newNode; 44 | level++; 45 | } while(rand()%2 && level < MAX_LEVEL); 46 | } 47 | 48 | void printList(SkipList* list) { 49 | Node* curr; 50 | for(int i = MAX_LEVEL - 1; i >= 0; i--) { 51 | curr = list->head; 52 | printf("Level %d: ", i); 53 | while(curr) { 54 | printf("%d ", curr->val); 55 | curr = curr->next[i]; 56 | } 57 | printf("\n"); 58 | } 59 | } 60 | 61 | void release(SkipList* list) { 62 | Node* currNode = list->head; 63 | Node* tempNode; 64 | while (currNode) { 65 | tempNode = currNode; 66 | currNode = currNode->next[0]; 67 | free(tempNode); 68 | } 69 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-29-huffman-coding/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = NULL; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | list_t* push_list(list_t* list, void* value) { 15 | // List is empty - create new node and return it 16 | if(list == NULL) { 17 | list_t* new_head = init_list(); 18 | new_head->value = value; 19 | return new_head; 20 | } 21 | 22 | // End of the list - create new node and attach it 23 | if(list->next == NULL) { 24 | list->next = push_list(list->next, value); 25 | return list; 26 | } 27 | 28 | // Middle of the list - continue recursively to the end 29 | push_list(list->next, value); 30 | return list; 31 | } 32 | 33 | void* pop_list(list_t** list) { 34 | if(*list == NULL) { 35 | return NULL; 36 | } 37 | 38 | list_t* old_head = *list; 39 | 40 | void* result = (*list)->value; 41 | *list = (*list)->next; 42 | 43 | free(old_head); 44 | 45 | return result; 46 | } 47 | 48 | void* list_get_at( 49 | list_t* list, 50 | unsigned int index 51 | ) { 52 | int len = list_length(list); 53 | if(len < index) return NULL; 54 | 55 | list_t* curr = list; 56 | int i = 0; 57 | 58 | while(i < index) { 59 | curr = curr->next; 60 | i++; 61 | } 62 | 63 | return curr->value; 64 | } 65 | 66 | int list_length(list_t* list) { 67 | int count = 0; 68 | while(list != NULL) { 69 | count++; 70 | list = list->next; 71 | } 72 | 73 | return count; 74 | } 75 | 76 | void destroy_list(list_t* list) { 77 | while(list != NULL) { 78 | list_t* tmp = list; 79 | list = list->next; 80 | 81 | free(tmp); 82 | } 83 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-05-10-huffman-coding-2/list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "list.h" 4 | 5 | list_t* init_list() { 6 | list_t* list = (list_t*)malloc(sizeof(list_t)); 7 | 8 | list->value = NULL; 9 | list->next = NULL; 10 | 11 | return list; 12 | } 13 | 14 | list_t* push_list(list_t* list, void* value) { 15 | // List is empty - create new node and return it 16 | if(list == NULL) { 17 | list_t* new_head = init_list(); 18 | new_head->value = value; 19 | return new_head; 20 | } 21 | 22 | // End of the list - create new node and attach it 23 | if(list->next == NULL) { 24 | list->next = push_list(list->next, value); 25 | return list; 26 | } 27 | 28 | // Middle of the list - continue recursively to the end 29 | push_list(list->next, value); 30 | return list; 31 | } 32 | 33 | void* pop_list(list_t** list) { 34 | if(*list == NULL) { 35 | return NULL; 36 | } 37 | 38 | list_t* old_head = *list; 39 | 40 | void* result = (*list)->value; 41 | *list = (*list)->next; 42 | 43 | free(old_head); 44 | 45 | return result; 46 | } 47 | 48 | void* list_get_at( 49 | list_t* list, 50 | unsigned int index 51 | ) { 52 | int len = list_length(list); 53 | if(len < index) return NULL; 54 | 55 | list_t* curr = list; 56 | int i = 0; 57 | 58 | while(i < index) { 59 | curr = curr->next; 60 | i++; 61 | } 62 | 63 | return curr->value; 64 | } 65 | 66 | int list_length(list_t* list) { 67 | int count = 0; 68 | while(list != NULL) { 69 | count++; 70 | list = list->next; 71 | } 72 | 73 | return count; 74 | } 75 | 76 | void destroy_list(list_t* list) { 77 | while(list != NULL) { 78 | list_t* tmp = list; 79 | list = list->next; 80 | 81 | free(tmp); 82 | } 83 | } -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-11-graph-3/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "graph.h" 4 | #include "list.h" 5 | 6 | void demo_list() { 7 | list_t* my_list = push_list(NULL, (void*)1); 8 | for(int i = 2; i < 10; i++) 9 | push_list(my_list, (void*)i); 10 | 11 | printf("List size: %d\n", list_length(my_list)); 12 | 13 | while(list_length(my_list) > 3) { 14 | printf("%d\n", (int)pop_list(&my_list)); 15 | } 16 | 17 | destroy_list(my_list); 18 | } 19 | 20 | void demo_graph() { 21 | graph_edge_t* my_edge = init_graph_edge(1); 22 | graph_node_t* my_node = init_graph_node("Test"); 23 | graph_t* my_graph = init_graph(); 24 | 25 | add_graph_node(my_graph, "test1"); 26 | add_graph_node(my_graph, "test2"); 27 | add_graph_node(my_graph, "test3"); 28 | add_graph_node(my_graph, "test4"); 29 | add_graph_node(my_graph, "test5"); 30 | 31 | connect_nodes( 32 | find_node_by_name(my_graph, "test1"), 33 | find_node_by_name(my_graph, "test2"), 34 | 5 35 | ); 36 | connect_nodes( 37 | find_node_by_name(my_graph, "test1"), 38 | find_node_by_name(my_graph, "test3"), 39 | 1 40 | ); 41 | connect_nodes( 42 | find_node_by_name(my_graph, "test2"), 43 | find_node_by_name(my_graph, "test4"), 44 | 2 45 | ); 46 | connect_nodes( 47 | find_node_by_name(my_graph, "test2"), 48 | find_node_by_name(my_graph, "test5"), 49 | 1 50 | ); 51 | connect_nodes( 52 | find_node_by_name(my_graph, "test3"), 53 | find_node_by_name(my_graph, "test5"), 54 | 3 55 | ); 56 | 57 | print_graph(my_graph); 58 | 59 | destroy_graph_edge(my_edge); 60 | destroy_graph_node(my_node); 61 | destroy_graph(my_graph); 62 | } 63 | 64 | int main() { 65 | // demo_list(); 66 | demo_graph(); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /2023-2024/10b/2024-03-18-dijkstra-2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "graph.h" 4 | #include "list.h" 5 | 6 | void demo_list() { 7 | list_t* my_list = push_list(NULL, (void*)1); 8 | for(int i = 2; i < 10; i++) 9 | push_list(my_list, (void*)i); 10 | 11 | printf("List size: %d\n", list_length(my_list)); 12 | 13 | while(list_length(my_list) > 3) { 14 | printf("%d\n", (int)pop_list(&my_list)); 15 | } 16 | 17 | destroy_list(my_list); 18 | } 19 | 20 | void demo_graph() { 21 | graph_edge_t* my_edge = init_graph_edge(1); 22 | graph_node_t* my_node = init_graph_node("Test"); 23 | graph_t* my_graph = init_graph(); 24 | 25 | add_graph_node(my_graph, "test1"); 26 | add_graph_node(my_graph, "test2"); 27 | add_graph_node(my_graph, "test3"); 28 | add_graph_node(my_graph, "test4"); 29 | add_graph_node(my_graph, "test5"); 30 | 31 | connect_nodes( 32 | find_node_by_name(my_graph, "test1"), 33 | find_node_by_name(my_graph, "test2"), 34 | 5 35 | ); 36 | connect_nodes( 37 | find_node_by_name(my_graph, "test1"), 38 | find_node_by_name(my_graph, "test3"), 39 | 1 40 | ); 41 | connect_nodes( 42 | find_node_by_name(my_graph, "test2"), 43 | find_node_by_name(my_graph, "test4"), 44 | 2 45 | ); 46 | connect_nodes( 47 | find_node_by_name(my_graph, "test2"), 48 | find_node_by_name(my_graph, "test5"), 49 | 1 50 | ); 51 | connect_nodes( 52 | find_node_by_name(my_graph, "test3"), 53 | find_node_by_name(my_graph, "test5"), 54 | 3 55 | ); 56 | 57 | print_graph(my_graph); 58 | 59 | destroy_graph_edge(my_edge); 60 | destroy_graph_node(my_node); 61 | destroy_graph(my_graph); 62 | } 63 | 64 | int main() { 65 | // demo_list(); 66 | demo_graph(); 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /2023-2024/10a/utils/graph_h.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include "graph_h.h" 6 | 7 | VertexNode *init_node(char *val, double weight) 8 | { 9 | VertexNode *node = (VertexNode *)malloc(sizeof(VertexNode)); 10 | node->val = strdup(val); 11 | node->next = NULL; 12 | node->weight = weight; 13 | 14 | return node; 15 | } 16 | 17 | Graph *init_graph() 18 | { 19 | Graph *graph = (Graph *)malloc(sizeof(Graph)); 20 | graph->adjList = init_hash_map(); 21 | 22 | return graph; 23 | } 24 | 25 | void addEdgeDirectional(Graph *graph, char *from, char *to, double weight) 26 | { 27 | VertexNode *newNode = init_node(to, weight); 28 | 29 | newNode->next = get(graph->adjList, from); 30 | set(graph->adjList, from, newNode); 31 | } 32 | 33 | void addEdge(Graph *graph, char *from, char *to, double weight) 34 | { 35 | addEdgeDirectional(graph, from, to, weight); 36 | addEdgeDirectional(graph, to, from, weight); 37 | } 38 | 39 | // char* strdup(char* str) { 40 | // char* new_str = (char*)malloc(strlen(str) + 1); 41 | // strcpy(new_str, str); 42 | // return new_str; 43 | // } 44 | 45 | void printGraph(Graph *graph) 46 | { 47 | for (int i = 0; i < HASH_SIZE; i++) 48 | { 49 | EntryNode *current = graph->adjList->array[i]; 50 | if (current == NULL) 51 | { 52 | continue; 53 | } 54 | 55 | while (current != NULL) 56 | { 57 | VertexNode *currentNode = (VertexNode *)current->val; 58 | printf("Neighbours of %s:\n", current->key); 59 | while (currentNode != NULL) 60 | { 61 | printf("%s(%f) ", currentNode->val, currentNode->weight); 62 | currentNode = currentNode->next; 63 | } 64 | current = current->next; 65 | printf("\n"); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-15-hashmap/map.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "map.h" 5 | #include "list.h" 6 | 7 | map_t* init_map(unsigned int size) { 8 | map_t* new_map = malloc(sizeof(map_t)); 9 | 10 | new_map->size = 0; 11 | new_map->hash_arr_size = size; 12 | // new_map->hash_arr = malloc(size * struct list_t*); 13 | new_map->hash_arr = calloc(sizeof(struct list_t*), size); 14 | 15 | return new_map; 16 | } 17 | 18 | unsigned int hash_func(char* key) { 19 | unsigned int hash = 0; 20 | for(int i = 0; i < strlen(key); i++) hash += key[i]; 21 | return hash; 22 | } 23 | 24 | int map_has_key(map_t* map, char* key) { 25 | // key -> hash 26 | // hash_arr[hash] ? 27 | // hash_arr[hash] has key ? 28 | unsigned int hash = hash_func(key); 29 | 30 | if(map->hash_arr[hash] == NULL) return 0; 31 | 32 | struct list_t* list = map->hash_arr[hash]; 33 | while(list != NULL) { 34 | struct map_node_t* kvp = list->value; 35 | if(strcmp(kvp->key, key) == 0) return 1; 36 | 37 | list = list->next; 38 | } 39 | 40 | return 0; 41 | } 42 | 43 | void map_add(map_t* map, char* key, void* value) { 44 | unsigned int hash = hash_func(key); 45 | 46 | if(map->hash_arr[hash] == NULL) { 47 | map->hash_arr[hash] = init_list(); 48 | } 49 | 50 | struct list_t* list = map->hash_arr[hash]; 51 | while(list != NULL) { 52 | struct map_node_t* kvp = list->value; 53 | if(strcmp(kvp->key, key) == 0) { 54 | kvp->value = value; 55 | return; 56 | } 57 | 58 | list = list->next; 59 | } 60 | 61 | struct map_node_t* new_kvp = malloc(sizeof(struct map_node_t)); 62 | new_kvp->key = key; 63 | new_kvp->value = value; 64 | 65 | push_list(list, new_kvp); 66 | } 67 | 68 | void map_remove(map_t* map, char* key); 69 | void* map_get(map_t* map, char* key); -------------------------------------------------------------------------------- /2023-2024/10b/2024-04-29-huffman-coding/map.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "map.h" 5 | #include "list.h" 6 | 7 | map_t* init_map(unsigned int size) { 8 | map_t* new_map = malloc(sizeof(map_t)); 9 | 10 | new_map->size = 0; 11 | new_map->hash_arr_size = size; 12 | // new_map->hash_arr = malloc(size * struct list_t*); 13 | new_map->hash_arr = calloc(sizeof(struct list_t*), size); 14 | 15 | return new_map; 16 | } 17 | 18 | unsigned int hash_func(char* key) { 19 | unsigned int hash = 0; 20 | for(int i = 0; i < strlen(key); i++) hash += key[i]; 21 | return hash; 22 | } 23 | 24 | int map_has_key(map_t* map, char* key) { 25 | // key -> hash 26 | // hash_arr[hash] ? 27 | // hash_arr[hash] has key ? 28 | unsigned int hash = hash_func(key); 29 | 30 | if(map->hash_arr[hash] == NULL) return 0; 31 | 32 | struct list_t* list = map->hash_arr[hash]; 33 | while(list != NULL) { 34 | struct map_node_t* kvp = list->value; 35 | if(strcmp(kvp->key, key) == 0) return 1; 36 | 37 | list = list->next; 38 | } 39 | 40 | return 0; 41 | } 42 | 43 | void map_add(map_t* map, char* key, void* value) { 44 | unsigned int hash = hash_func(key); 45 | 46 | if(map->hash_arr[hash] == NULL) { 47 | map->hash_arr[hash] = init_list(); 48 | } 49 | 50 | struct list_t* list = map->hash_arr[hash]; 51 | while(list != NULL) { 52 | struct map_node_t* kvp = list->value; 53 | if(strcmp(kvp->key, key) == 0) { 54 | kvp->value = value; 55 | return; 56 | } 57 | 58 | list = list->next; 59 | } 60 | 61 | struct map_node_t* new_kvp = malloc(sizeof(struct map_node_t)); 62 | new_kvp->key = key; 63 | new_kvp->value = value; 64 | 65 | push_list(list, new_kvp); 66 | } 67 | 68 | void map_remove(map_t* map, char* key); 69 | void* map_get(map_t* map, char* key); -------------------------------------------------------------------------------- /2023-2024/10b/2024-05-10-huffman-coding-2/map.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "map.h" 5 | #include "list.h" 6 | 7 | map_t* init_map(unsigned int size) { 8 | map_t* new_map = malloc(sizeof(map_t)); 9 | 10 | new_map->size = 0; 11 | new_map->hash_arr_size = size; 12 | // new_map->hash_arr = malloc(size * struct list_t*); 13 | new_map->hash_arr = calloc(sizeof(struct list_t*), size); 14 | 15 | return new_map; 16 | } 17 | 18 | unsigned int hash_func(char* key) { 19 | unsigned int hash = 0; 20 | for(int i = 0; i < strlen(key); i++) hash += key[i]; 21 | return hash; 22 | } 23 | 24 | int map_has_key(map_t* map, char* key) { 25 | // key -> hash 26 | // hash_arr[hash] ? 27 | // hash_arr[hash] has key ? 28 | unsigned int hash = hash_func(key); 29 | 30 | if(map->hash_arr[hash] == NULL) return 0; 31 | 32 | struct list_t* list = map->hash_arr[hash]; 33 | while(list != NULL) { 34 | struct map_node_t* kvp = list->value; 35 | if(strcmp(kvp->key, key) == 0) return 1; 36 | 37 | list = list->next; 38 | } 39 | 40 | return 0; 41 | } 42 | 43 | void map_add(map_t* map, char* key, void* value) { 44 | unsigned int hash = hash_func(key); 45 | 46 | if(map->hash_arr[hash] == NULL) { 47 | map->hash_arr[hash] = init_list(); 48 | } 49 | 50 | struct list_t* list = map->hash_arr[hash]; 51 | while(list != NULL) { 52 | struct map_node_t* kvp = list->value; 53 | if(strcmp(kvp->key, key) == 0) { 54 | kvp->value = value; 55 | return; 56 | } 57 | 58 | list = list->next; 59 | } 60 | 61 | struct map_node_t* new_kvp = malloc(sizeof(struct map_node_t)); 62 | new_kvp->key = key; 63 | new_kvp->value = value; 64 | 65 | push_list(list, new_kvp); 66 | } 67 | 68 | void map_remove(map_t* map, char* key); 69 | void* map_get(map_t* map, char* key); -------------------------------------------------------------------------------- /2024-2025/10a/2024-10-23-mergeSort/main.c: -------------------------------------------------------------------------------- 1 | #include "../utils/vector.h" 2 | 3 | void merge(vector*v, int l, int r, int mid) { 4 | vector* v1 = init_vector(2); 5 | vector* v2 = init_vector(2); 6 | 7 | // n / 2 8 | for (int i = l; i <= mid; i++) { 9 | push(v1, v->arr[i]); 10 | } 11 | // n / 2 12 | for (int i = mid + 1; i <= r; i++) { 13 | push(v2, v->arr[i]); 14 | } 15 | // N 16 | 17 | int i1 = 0; 18 | int i2 = 0; 19 | int k = 0; 20 | // N1 + N2 21 | while (i1 < v1->size && i2 < v2->size) { 22 | //printf("%d %d\n", i1, i2); 23 | if (v1->arr[i1] < v2->arr[i2]) { 24 | v->arr[l + k] = v1->arr[i1]; 25 | i1++; 26 | } else { 27 | v->arr[l + k] = v2->arr[i2]; 28 | i2++; 29 | } 30 | k++; 31 | } 32 | 33 | while (i1 < v1->size) { 34 | v->arr[l + k] = v1->arr[i1]; 35 | i1++; 36 | k++; 37 | } 38 | 39 | while (i2 < v2->size) { 40 | v->arr[l + k] = v2->arr[i2]; 41 | i2++; 42 | k++; 43 | } 44 | 45 | free_vector(v1); 46 | free_vector(v2); 47 | } 48 | 49 | void mergeSortR(vector* v, int l, int r) { 50 | if (l >= r) { 51 | return; 52 | } 53 | 54 | int mid = (l + r) / 2; 55 | 56 | mergeSortR(v, l, mid); 57 | mergeSortR(v, mid + 1, r); 58 | 59 | merge(v, l, r, mid); 60 | } 61 | 62 | void mergeSort(vector *v) { 63 | mergeSortR(v, 0, v->size - 1); 64 | } 65 | 66 | int main() { 67 | vector* v = init_vector(2); 68 | push(v, 10); 69 | push(v, 50); 70 | push(v, 30); 71 | push(v, 20); 72 | push(v, 25); 73 | push(v, 35); 74 | push(v, -100); 75 | push(v, -10); 76 | push(v, 70); 77 | push(v, 30); 78 | push(v, 60); 79 | push(v, 250); 80 | push(v, 39); 81 | push(v, -100); 82 | 83 | mergeSort(v); 84 | print_vector(v); 85 | 86 | return 0; 87 | } -------------------------------------------------------------------------------- /2024-2025/10v/2025_04_23 huffman/pqueue.c: -------------------------------------------------------------------------------- 1 | #include "pqueue.h" 2 | #include 3 | 4 | PQueue* init_pq() { 5 | PQueue* pq = (PQueue* )malloc(sizeof(PQueue)); 6 | pq->size = 0; 7 | return pq; 8 | } 9 | 10 | PQNode* init_pq_node(void* data, float key) { 11 | PQNode* node = (PQNode* )malloc(sizeof(PQNode)); 12 | node->data = data; 13 | node->key = key; 14 | return node; 15 | } 16 | 17 | void swap(PQNode** a, PQNode** b) { 18 | PQNode* temp =* a; 19 | *a = *b; 20 | *b = temp; 21 | } 22 | 23 | void siftDown(PQueue* pq, int i) { 24 | int swapped = 1; 25 | 26 | while (swapped) { 27 | swapped = 0; 28 | int smallest = i; 29 | int left = 2 * i + 1; 30 | int right = 2 * i + 2; 31 | 32 | if (left < pq->size && pq->arr[left]->key < pq->arr[smallest]->key) { 33 | smallest = left; 34 | } 35 | if (right < pq->size && pq->arr[right]->key < pq->arr[smallest]->key) { 36 | smallest = right; 37 | } 38 | 39 | if (i != smallest) { 40 | swap(&pq->arr[i], &pq->arr[smallest]); 41 | i = smallest; 42 | swapped = 1; 43 | } 44 | } 45 | } 46 | 47 | PQNode* deleteMin(PQueue* pq) { 48 | if (pq->size == 0) return NULL; 49 | 50 | PQNode* res = pq->arr[0]; 51 | pq->arr[0] = pq->arr[pq->size - 1]; 52 | pq->size--; 53 | siftDown(pq, 0); 54 | 55 | return res; 56 | } 57 | 58 | void pqInsert(PQueue* pq, void* data, float key) { 59 | if (pq->size >= MAX_PQ_NODES) return; 60 | 61 | PQNode* newNode = init_pq_node(data, key); 62 | pq->arr[pq->size] = newNode; 63 | 64 | int current = pq->size++; 65 | int parent = (current - 1) / 2; 66 | 67 | while (current > 0 && pq->arr[current]->key < pq->arr[parent]->key) { 68 | swap(&pq->arr[current], &pq->arr[parent]); 69 | current = parent; 70 | parent = (current - 1) / 2; 71 | } 72 | } --------------------------------------------------------------------------------