Add module5_datastructures.c
This commit is contained in:
253
src/c_examples/module5_datastructures.c
Normal file
253
src/c_examples/module5_datastructures.c
Normal file
@@ -0,0 +1,253 @@
|
||||
// ============================================
|
||||
// Modul 5: Datenstrukturen
|
||||
// Beispiele in C
|
||||
// ============================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// ============================================
|
||||
// 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;
|
||||
}
|
||||
Reference in New Issue
Block a user