Skip to main content

c-data-structures

Use when fundamental C data structures including arrays, structs, linked lists, trees, and hash tables with memory-efficient implementations.

Source facts

Repository
TheBushidoCollective/han
Last source activity
February 11, 2026 at 17:47
Detected SKILL.md language
English
Stars
198
Forks
21

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
c-data-structures
user-invocable
false
description
Use when fundamental C data structures including arrays, structs, linked lists, trees, and hash tables with memory-efficient implementations.
allowed-tools
["Read","Write","Edit","Grep","Glob","Bash"]
# C Data Structures Data structures in C require manual memory management and careful pointer manipulation. Understanding how to implement and use fundamental data structures is essential for building efficient C applications. This skill covers arrays, structs, linked lists, trees, and hash tables. ## Arrays and Dynamic Arrays Arrays provide contiguous memory storage with O(1) access time. Dynamic arrays offer flexibility at the cost of occasional reallocation. ### Static Arrays ```c #include <stdio.h> #include <string.h> // Working with static arrays void array_operations(void) { int numbers[5] = {1, 2, 3, 4, 5}; // Array length (only works with static arrays) size_t length = sizeof(numbers) / sizeof(numbers[0]); // Iterate through array for (size_t i = 0; i < length; i++) { printf("%d ", numbers[i]); } printf("\n"); // Array as function parameter (decays to pointer) int sum = 0; for (size_t i = 0; i < length; i++) { sum += numbers[i]; } printf("Sum: %d\n", sum); } ``` ### Dynamic Arrays ```c #include <stdlib.h> #include <string.h> typedef struct { int *data; size_t size; size_t capacity; } DynamicArray; // Initialize dynamic array DynamicArray *array_create(size_t initial_capacity) { DynamicArray *arr = malloc(sizeof(DynamicArray)); if (!arr) return NULL; arr->data = malloc(initial_capacity * sizeof(int)); if (!arr->data) { free(arr); return NULL; } arr->size = 0; arr->capacity = initial_capacity; return arr; } // Append element to array int array_push(DynamicArray *arr, int value) { if (arr->size >= arr->capacity) { size_t new_capacity = arr->capacity * 2; int *new_data = realloc(arr->data, new_capacity * sizeof(int)); if (!new_data) return -1; arr->data = new_data; arr->capacity = new_capacity; } arr->data[arr->size++] = value; return 0; } // Free array memory void array_free(DynamicArray *arr) { if (arr) { free(arr->data); free(arr); } } ``` ## Structs and Data Modeling Structs group related data together, enabling complex data modeling and organization. ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // Define a structure typedef struct { char name[50]; int age; float salary; } Employee; // Create and initialize struct Employee *employee_create(const char *name, int age, float salary) { Employee *emp = malloc(sizeof(Employee)); if (!emp) return NULL; strncpy(emp->name, name, sizeof(emp->name) - 1); emp->name[sizeof(emp->name) - 1] = '\0'; emp->age = age; emp->salary = salary; return emp; } // Struct with nested structures typedef struct { int x; int y; } Point; typedef struct { Point top_left; Point bottom_right; } Rectangle; // Calculate rectangle area int rectangle_area(const Rectangle *rect) { int width = rect->bottom_right.x - rect->top_left.x; int height = rect->bottom_right.y - rect->top_left.y; return width * height; } ``` ## Linked Lists Linked lists provide dynamic insertion and deletion with O(1) time complexity for operations at known positions. ```c #include <stdio.h> #include <stdlib.h> // Singly linked list node typedef struct Node { int data; struct Node *next; } Node; typedef struct { Node *head; size_t size; } LinkedList; // Create new list LinkedList *list_create(void) { LinkedList *list = malloc(sizeof(LinkedList)); if (!list) return NULL; list->head = NULL; list->size = 0; return list; } // Insert at beginning int list_prepend(LinkedList *list, int data) { Node *node = malloc(sizeof(Node)); if (!node) return -1; node->data = data; node->next = list->head; list->head = node; list->size++; return 0; } // Insert at end int list_append(LinkedList *list, int data) { Node *node = malloc(sizeof(Node)); if (!node) return -1; node->data = data; node->next = NULL; if (!list->head) { list->head = node; } else { Node *current = list->head; while (current->next) { current = current->next; } current->next = node; } list->size++; return 0; } // Remove first occurrence of value int list_remove(LinkedList *list, int data) { if (!list->head) return -1; // Remove head node if (list->head->data == data) { Node *temp = list->head; list->head = list->head->next; free(temp); list->size--; return 0; } // Remove other node Node *current = list->head; while (current->next) { if (current->next->data == data) { Node *temp = current->next; current->next = current->next->next; free(temp); list->size--; return 0; } current = current->next; } return -1; // Not found } // Free entire list void list_free(LinkedList *list) { if (!list) return; Node *current = list->head; while (current) { Node *next = current->next; free(current); current = next; } free(list); } ``` ## Doubly Linked Lists Doubly linked lists allow bidirectional traversal with previous and next pointers. ```c #include <stdlib.h> // Doubly linked list node typedef struct DNode { int data; struct DNode *prev; struct DNode *next; } DNode; typedef struct { DNode *head; DNode *tail; size_t size; } DoublyLinkedList; // Create new doubly linked list DoublyLinkedList *dlist_create(void) { DoublyLinkedList *list = malloc(sizeof(DoublyLinkedList)); if (!list) return NULL; list->head = NULL; list->tail = NULL; list->size = 0; return list; } // Insert at end (O(1) with tail pointer) int dlist_append(DoublyLinkedList *list, int data) { DNode *node = malloc(sizeof(DNode)); if (!node) return -1; node->data = data; node->next = NULL; node->prev = list->tail; if (list->tail) { list->tail->next = node; } else { list->head = node; } list->tail = node; list->size++; return 0; } // Remove from end (O(1) with tail pointer) int dlist_pop(DoublyLinkedList *list, int *data) { if (!list->tail) return -1; *data = list->tail->data; DNode *node = list->tail; if (list->tail->prev) { list->tail = list->tail->prev; list->tail->next = NULL; } else { list->head = NULL; list->tail = NULL; } free(node); list->size--; return 0; } ``` ## Binary Trees Binary trees organize data hierarchically, enabling efficient searching, insertion, and traversal operations. ```c #include <stdio.h> #include <stdlib.h> // Binary tree node typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; // Create new tree node TreeNode *tree_node_create(int data) { TreeNode *node = malloc(sizeof(TreeNode)); if (!node) return NULL; node->data = data; node->left = NULL; node->right = NULL; return node; } // Insert into binary search tree TreeNode *bst_insert(TreeNode *root, int data) { if (!root) { return tree_node_create(data); } if (data < root->data) { root->left = bst_insert(root->left, data); } else if (data > root->data) { root->right = bst_insert(root->right, data); } return root; } // Search in binary search tree TreeNode *bst_search(TreeNode *root, int data) { if (!root || root->data == data) { return root; } if (data < root->data) { return bst_search(root->left, data); } return bst_search(root->right, data); } // In-order traversal (sorted order for BST) void tree_inorder(TreeNode *root) { if (!root) return; tree_inorder(root->left); printf("%d ", root->data); tree_inorder(root->right); } // Free entire tree void tree_free(TreeNode *root) { if (!root) return; tree_free(root->left); tree_free(root->right); free(root); } ``` ## Hash Tables Hash tables provide O(1) average-case insertion, deletion, and lookup using hash functions and collision resolution. ```c #include <stdlib.h> #include <string.h> #define HASH_TABLE_SIZE 100 // Hash table entry typedef struct Entry { char *key; int value; struct Entry *next; // For collision chaining } Entry; // Hash table typedef struct { Entry *buckets[HASH_TABLE_SIZE]; size_t size; } HashTable; // Hash function (djb2) unsigned long hash(const char *str) { unsigned long hash = 5381; int c; while ((c = *str++)) { hash = ((hash << 5) + hash) + c; } return hash % HASH_TABLE_SIZE; } // Create hash table HashTable *hashtable_create(void) { HashTable *table = malloc(sizeof(HashTable)); if (!table) return NULL; for (int i = 0; i < HASH_TABLE_SIZE; i++) { table->buckets[i] = NULL; } table->size = 0; return table; } // Insert or update key-value pair int hashtable_set(HashTable *table, const char *key, int value) { unsigned long index = hash(key); Entry *entry = table->buckets[index]; // Check if key exists while (entry) { if (strcmp(entry->key, key) == 0) { entry->value = value; return 0; } entry = entry->next; } // Create new entry Entry *new_entry = malloc(sizeof(Entry)); if (!new_entry) return -1; new_entry->key = strdup(key); if (!new_entry->key) { free(new_entry); return -1; } new_entry->value = value; new_entry->next = table->buckets[index]; table->buckets[index] = new_entry; table->size++; return 0; } // Get value by key int hashtable_get(HashTable *table, const char *key, int *value) { unsigned long index = hash(key); Entry *entry = table->buckets[index]; while (entry) { if (strcmp(entry->key, key) == 0) { *value = entry->value; return 0; } entry = entry->next; } return -1; // Not found } // Free hash table void hashtable_free(HashTable *table) { if (!table) return; for (int i = 0; i < HASH_TABLE_SIZE; i++) { Entry *entry = table->buckets[i]; while (entry) { Entry *next = entry->next; free(entry->key); free(entry); entry = next; }
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub