#include #include #include #include #define MAX_TASKS 100 struct Task { uint32_t due; uint32_t intervall; // Funktionspointer etc. // Arguments // Debug: int pid; } tasks[MAX_TASKS]; int taskcount=0; // Zwei Elemente vertauschen. // für größere sizeof(Task) macht ein Umstellen des Arrays auf Pointer Sinn. void swap(int a, int b) { struct Task tmp=tasks[a]; tasks[a]=tasks[b]; tasks[b]=tmp; } #define LEFT(i) ((i)*2+1) #define RIGHT(i) ((i)*2+2) #define PARENT(i) ((i-1)/2) // An Knoten "i" die Heap-Bedingung herstellen // Laufzeit O(log n) void heapify(int i) { // Wir suchen unter diesem und direkten Kindern den kleinsten Knoten int kleinster=i; int left=LEFT(i); int right=RIGHT(i); if (left < taskcount && tasks[left].due < tasks[kleinster].due) kleinster=left; if (right < taskcount && tasks[right].due < tasks[kleinster].due) kleinster=right; if (kleinster == i) return; // Passt schon // Ansonsten tauschen, kleinsten Knoten Richtung Wurzel wandern lassen. swap(i, kleinster); // Tail-rekursion heapify(kleinster); } // Neuen Heap aus unsortierten Daten erstellen, dafür // beginnend von den Blättern "heapify" aufrufen. // Gesamt-Laufzeit ist trotzem nur O(n), // was nicht ganz offensichtlich ist. void build_heap() { if (!taskcount) return; for (int i = taskcount/2-1; i>=0; --i) heapify(i); } // Übungsaufgaben für den geneigten Leser: // - Funktion um (dynamisch) einen Task hinzuzufügen, solange taskcount