diff --git a/src/c_examples/module5_datastructures.c b/src/c_examples/module5_datastructures.c new file mode 100644 index 0000000..7ca6247 --- /dev/null +++ b/src/c_examples/module5_datastructures.c @@ -0,0 +1,253 @@ +// ============================================ +// Modul 5: Datenstrukturen +// Beispiele in C +// ============================================ + +#include +#include +#include +#include + +// ============================================ +// Beispiel 5.1: Dynamisches Array (Vektor) +// ============================================ + +typedef struct { + int* data; // Pointer zu Array + int size; // Aktuelle Elemente + int capacity; // Maximale Kapazität +} Vector; + +// Konstruktor +Vector* vector_create(int initial_capacity) { + Vector* v = malloc(sizeof(Vector)); + v->data = malloc(initial_capacity * sizeof(int)); + v->size = 0; + v->capacity = initial_capacity; + return v; +} + +// Destruktor +void vector_destroy(Vector* v) { + free(v->data); + free(v); +} + +// Push (am Ende hinzufügen) +void vector_push(Vector* v, int value) { + // Kapazität erweitern wenn nötig + if (v->size >= v->capacity) { + v->capacity *= 2; + v->data = realloc(v->data, v->capacity * sizeof(int)); + } + v->data[v->size++] = value; +} + +// Get (Zugriff) +int vector_get(Vector* v, int index) { + if (index < 0 || index >= v->size) { + fprintf(stderr, "Index out of bounds!\n"); + exit(1); + } + return v->data[index]; +} + +// ============================================ +// Beispiel 5.2: Linked List +// ============================================ + +typedef struct Node { + int data; + struct Node* next; +} Node; + +typedef struct { + Node* head; + int size; +} LinkedList; + +LinkedList* list_create() { + LinkedList* list = malloc(sizeof(LinkedList)); + list->head = NULL; + list->size = 0; + return list; +} + +void list_prepend(LinkedList* list, int value) { + Node* new_node = malloc(sizeof(Node)); + new_node->data = value; + new_node->next = list->head; + list->head = new_node; + list->size++; +} + +void list_print(LinkedList* list) { + Node* current = list->head; + printf("List: "); + while (current != NULL) { + printf("%d → ", current->data); + current = current->next; + } + printf("NULL\n"); +} + +void list_destroy(LinkedList* list) { + Node* current = list->head; + while (current != NULL) { + Node* temp = current; + current = current->next; + free(temp); + } + free(list); +} + +// ============================================ +// Beispiel 5.3: Stack (LIFO) +// ============================================ + +typedef struct { + int* items; + int top; + int capacity; +} Stack; + +Stack* stack_create(int capacity) { + Stack* s = malloc(sizeof(Stack)); + s->items = malloc(capacity * sizeof(int)); + s->top = -1; + s->capacity = capacity; + return s; +} + +bool stack_is_empty(Stack* s) { + return s->top == -1; +} + +bool stack_is_full(Stack* s) { + return s->top == s->capacity - 1; +} + +void stack_push(Stack* s, int value) { + if (stack_is_full(s)) { + printf("Stack Overflow!\n"); + return; + } + s->items[++s->top] = value; +} + +int stack_pop(Stack* s) { + if (stack_is_empty(s)) { + printf("Stack Underflow!\n"); + return -1; + } + return s->items[s->top--]; +} + +int stack_peek(Stack* s) { + if (stack_is_empty(s)) return -1; + return s->items[s->top]; +} + +// ============================================ +// Beispiel 5.4: Queue (FIFO) +// ============================================ + +typedef struct { + int* items; + int front, rear; + int capacity; + int size; +} Queue; + +Queue* queue_create(int capacity) { + Queue* q = malloc(sizeof(Queue)); + q->items = malloc(capacity * sizeof(int)); + q->front = 0; + q->rear = -1; + q->capacity = capacity; + q->size = 0; + return q; +} + +bool queue_is_empty(Queue* q) { + return q->size == 0; +} + +bool queue_is_full(Queue* q) { + return q->size == q->capacity; +} + +void queue_enqueue(Queue* q, int value) { + if (queue_is_full(q)) { + printf("Queue Full!\n"); + return; + } + q->rear = (q->rear + 1) % q->capacity; // Circular + q->items[q->rear] = value; + q->size++; +} + +int queue_dequeue(Queue* q) { + if (queue_is_empty(q)) { + printf("Queue Empty!\n"); + return -1; + } + int value = q->items[q->front]; + q->front = (q->front + 1) % q->capacity; + q->size--; + return value; +} + +// ============================================ +// Hauptprogramm +// ============================================ +int main() { + printf("=== Modul 5: Datenstrukturen ===\n\n"); + + // Vector Demo + printf("--- Vector (Dynamisches Array) ---\n"); + Vector* v = vector_create(2); + vector_push(v, 10); + vector_push(v, 20); + vector_push(v, 30); // Erweitert automatisch + printf("Vector: %d, %d, %d\n", vector_get(v, 0), vector_get(v, 1), vector_get(v, 2)); + vector_destroy(v); + + // Linked List Demo + printf("\n--- Linked List ---\n"); + LinkedList* list = list_create(); + list_prepend(list, 30); + list_prepend(list, 20); + list_prepend(list, 10); + list_print(list); + printf("Size: %d\n", list->size); + list_destroy(list); + + // Stack Demo + printf("\n--- Stack (LIFO) ---\n"); + Stack* s = stack_create(5); + stack_push(s, 10); + stack_push(s, 20); + stack_push(s, 30); + printf("Top: %d\n", stack_peek(s)); + printf("Pop: %d\n", stack_pop(s)); + printf("Pop: %d\n", stack_pop(s)); + + // Queue Demo + printf("\n--- Queue (FIFO) ---\n"); + Queue* q = queue_create(5); + queue_enqueue(q, 10); + queue_enqueue(q, 20); + queue_enqueue(q, 30); + printf("Dequeue: %d\n", queue_dequeue(q)); // 10 + printf("Dequeue: %d\n", queue_dequeue(q)); // 20 + + printf("\n=== Wichtige Konzepte ===\n"); + printf("1. Array: O(1) Zugriff, O(n) Einfügen/Löschen\n"); + printf("2. Linked List: O(n) Zugriff, O(1) Einfügen/Löschen\n"); + printf("3. Stack: LIFO - Last In, First Out\n"); + printf("4. Queue: FIFO - First In, First Out\n"); + printf("5. Dynamic Arrays erweitern sich automatisch\n"); + + return 0; +}