Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3837685b21 | ||
|
|
9a9f0d6bb1 |
@@ -93,6 +93,11 @@ TreeNode *addToTree(TreeNode *wurzel,
|
|||||||
return wurzel;
|
return wurzel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Die Funktion gibt bei jedem Aufruf das nächste Element des Binärbaums in **Inorder-Reihenfolge**
|
||||||
|
zurück und merkt sich intern, wo sie zuletzt war.
|
||||||
|
*/
|
||||||
|
|
||||||
void *nextTreeData(TreeNode *wurzel)
|
void *nextTreeData(TreeNode *wurzel)
|
||||||
{
|
{
|
||||||
static StackNode *iteratorStack = NULL; // interner Zustand über Aufrufe hinweg
|
static StackNode *iteratorStack = NULL; // interner Zustand über Aufrufe hinweg
|
||||||
@@ -110,8 +115,8 @@ void *nextTreeData(TreeNode *wurzel)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Nächsten Knoten holen (oberstes Stack-Element)
|
// Nächsten Knoten holen (oberstes Stack-Element)
|
||||||
TreeNode *aktuellerKnoten = (TreeNode *)top(iteratorStack);
|
TreeNode *aktuellerKnoten = (TreeNode *)top(iteratorStack); //Oberstes Element zurück
|
||||||
iteratorStack = pop(iteratorStack);
|
iteratorStack = pop(iteratorStack); // entfernt Oberstes Element
|
||||||
|
|
||||||
// Falls rechter Teilbaum existiert: dessen linke Kette ablegen
|
// Falls rechter Teilbaum existiert: dessen linke Kette ablegen
|
||||||
if (aktuellerKnoten->right != NULL)
|
if (aktuellerKnoten->right != NULL)
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ StackNode *push(StackNode *stack, void *data)
|
|||||||
if(node == NULL)
|
if(node == NULL)
|
||||||
return stack; // allocation failed -> return unchanged stack
|
return stack; // allocation failed -> return unchanged stack
|
||||||
|
|
||||||
node->data = data; // Setze Daten
|
node->data = data; // Set the data for the new node
|
||||||
node->next = stack; // Setze nächsten Knoten auf aktuellen Stack
|
node->next = stack; // New node points to the previous top of the stack
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ StackNode *pop(StackNode *stack)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
StackNode *next = stack->next;
|
StackNode *next = stack->next;
|
||||||
// Speicher des aktuellen Knotens freigeben
|
// Do NOT free stack->data here; caller owns the pointed data
|
||||||
free(stack);
|
free(stack);
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-5
@@ -3,7 +3,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "bintree.h"
|
#include "bintree.h"
|
||||||
|
|
||||||
// comparator for unsigned int values stored by value in heap
|
// Vergleichsfunktion für unsigned int
|
||||||
static int cmp_uint_ptr(const void *a, const void *b)
|
static int cmp_uint_ptr(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
unsigned int va = *(const unsigned int *)a;
|
unsigned int va = *(const unsigned int *)a;
|
||||||
@@ -19,7 +19,7 @@ int main(void)
|
|||||||
unsigned int vals[] = {5, 2, 8, 1, 3, 7, 9};
|
unsigned int vals[] = {5, 2, 8, 1, 3, 7, 9};
|
||||||
const size_t n = sizeof(vals)/sizeof(vals[0]);
|
const size_t n = sizeof(vals)/sizeof(vals[0]);
|
||||||
|
|
||||||
// insert values (copy made by addToTree)
|
// Werte in den Baum einfügen
|
||||||
for(size_t i = 0; i < n; i++)
|
for(size_t i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
int isDup = 0;
|
int isDup = 0;
|
||||||
@@ -27,22 +27,25 @@ int main(void)
|
|||||||
if(root == NULL && isDup == 0) { fprintf(stderr, "addToTree allocation failed\n"); return 1; }
|
if(root == NULL && isDup == 0) { fprintf(stderr, "addToTree allocation failed\n"); return 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Baumgröße prüfen
|
||||||
unsigned int sz = treeSize(root);
|
unsigned int sz = treeSize(root);
|
||||||
if(sz != n) { fprintf(stderr, "treeSize expected %zu got %u\n", n, sz); clearTree(root); return 2; }
|
if(sz != n) { fprintf(stderr, "treeSize expected %zu got %u\n", n, sz); clearTree(root); return 2; }
|
||||||
|
|
||||||
// inorder traversal using nextTreeData
|
// Inorder-Traversierung (muss sortiert sein)
|
||||||
unsigned int last = 0;
|
unsigned int last = 0;
|
||||||
int first = 1;
|
int first = 1;
|
||||||
unsigned int *data = nextTreeData(root);
|
unsigned int *data = nextTreeData(root);
|
||||||
while(data != NULL)
|
while(data != NULL)
|
||||||
{
|
{
|
||||||
unsigned int v = *data;
|
unsigned int v = *data;
|
||||||
|
// Prüfen, ob Reihenfolge korrekt ist
|
||||||
if(!first && v < last) { fprintf(stderr, "inorder traversal not sorted: %u after %u\n", v, last); clearTree(root); return 3; }
|
if(!first && v < last) { fprintf(stderr, "inorder traversal not sorted: %u after %u\n", v, last); clearTree(root); return 3; }
|
||||||
last = v; first = 0;
|
last = v; first = 0;
|
||||||
data = nextTreeData(NULL);
|
data = nextTreeData(NULL); // nächstes Element holen
|
||||||
}
|
}
|
||||||
|
|
||||||
clearTree(root);
|
clearTree(root); // Speicher freigeben
|
||||||
printf("test_bintree: OK\n");
|
printf("test_bintree: OK\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-19
@@ -8,45 +8,37 @@ int main(void)
|
|||||||
StackNode *s = NULL;
|
StackNode *s = NULL;
|
||||||
|
|
||||||
// push 3 integers
|
// push 3 integers
|
||||||
int *a = malloc(sizeof(int));
|
int *a = malloc(sizeof(int)); *a = 1; s = push(s, a);
|
||||||
*a = 1;
|
int *b = malloc(sizeof(int)); *b = 2; s = push(s, b);
|
||||||
s = push(s, a);
|
int *c = malloc(sizeof(int)); *c = 3; s = push(s, c);
|
||||||
int *b = malloc(sizeof(int));
|
|
||||||
*b = 2;
|
|
||||||
s = push(s, b);
|
|
||||||
int *c = malloc(sizeof(int));
|
|
||||||
*c = 3;
|
|
||||||
s = push(s, c);
|
|
||||||
|
|
||||||
// oben liegt c (3)
|
// top should be c (3)
|
||||||
int *topv = (int *)top(s);
|
int *topv = (int *)top(s);
|
||||||
if(topv == NULL || *topv != 3) { fprintf(stderr, "stack top expected 3\n"); return 1; }
|
if(topv == NULL || *topv != 3) { fprintf(stderr, "stack top expected 3\n"); return 1; }
|
||||||
|
|
||||||
// oben liegt nun 2
|
// pop -> now top should be 2
|
||||||
s = pop(s);
|
s = pop(s);
|
||||||
topv = (int *)top(s);
|
topv = (int *)top(s);
|
||||||
if(topv == NULL || *topv != 2) { fprintf(stderr, "stack top expected 2 after pop\n"); return 2; }
|
if(topv == NULL || *topv != 2) { fprintf(stderr, "stack top expected 2 after pop\n"); return 2; }
|
||||||
|
|
||||||
// oben liegt nun 1
|
// pop -> now top should be 1
|
||||||
s = pop(s);
|
s = pop(s);
|
||||||
topv = (int *)top(s);
|
topv = (int *)top(s);
|
||||||
if(topv == NULL || *topv != 1) { fprintf(stderr, "stack top expected 1 after pop\n"); return 3; }
|
if(topv == NULL || *topv != 1) { fprintf(stderr, "stack top expected 1 after pop\n"); return 3; }
|
||||||
|
|
||||||
// letzen Stapelinhalt holen
|
// pop last
|
||||||
s = pop(s);
|
s = pop(s);
|
||||||
if(s != NULL) { fprintf(stderr, "stack expected empty after popping all\n"); return 4; }
|
if(s != NULL) { fprintf(stderr, "stack expected empty after popping all\n"); return 4; }
|
||||||
|
|
||||||
// Eigenen Speicher freigeben
|
// free stored data (stack does not free data)
|
||||||
free(a);
|
free(a); free(b); free(c);
|
||||||
free(b);
|
|
||||||
free(c);
|
|
||||||
|
|
||||||
// test clearStack mit leerem Stack
|
// test clearStack on empty and small stacks
|
||||||
s = push(s, malloc(sizeof(int)));
|
s = push(s, malloc(sizeof(int)));
|
||||||
s = push(s, malloc(sizeof(int)));
|
s = push(s, malloc(sizeof(int)));
|
||||||
clearStack(s); // clearStack must free nodes but not payload; free payloads not necessary because we leaked intentionally for test of API
|
clearStack(s); // clearStack must free nodes but not payload; free payloads not necessary because we leaked intentionally for test of API
|
||||||
// Note: above payloads are not freed (stack API spec); this test ensures clearStack doesn't crash.
|
// Note: above payloads are not freed (stack API spec); this test ensures clearStack doesn't crash.
|
||||||
// Funktioniert alles
|
// Success
|
||||||
printf("test_stack: OK\n");
|
printf("test_stack: OK\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user