#include #include #include "stack.h" #include "bintree.h" static TreeNode *createTreeNode(const void *data, size_t dataSize) { TreeNode *node = NULL; if (data == NULL || dataSize == 0) { return NULL; } node = (TreeNode *)malloc(sizeof(TreeNode)); if (node == NULL) { return NULL; } node->data = malloc(dataSize); if (node->data == NULL) { free(node); return NULL; } memcpy(node->data, data, dataSize); node->left = NULL; node->right = NULL; return node; } // Adds a copy of data's pointer destination to the tree using compareFct for ordering. // If isDuplicate is NULL, duplicates are accepted. Otherwise duplicates are ignored and // isDuplicate is set to 1. If a new value is inserted, isDuplicate is set to 0. TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate) { int compareResult = 0; if (data == NULL || dataSize == 0 || compareFct == NULL) { return root; } if (root == NULL) { TreeNode *newNode = createTreeNode(data, dataSize); if (newNode != NULL && isDuplicate != NULL) { *isDuplicate = 0; } return newNode; } compareResult = compareFct(data, root->data); if (compareResult == 0 && isDuplicate != NULL) { *isDuplicate = 1; return root; } if (compareResult < 0) { root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); } else { root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate); } return root; } static StackNode *pushLeftPath(StackNode *stack, TreeNode *node) { while (node != NULL) { stack = push(stack, node); node = node->left; } return stack; } // Iterates over the tree in sorted order. If root is not NULL, a new iteration starts. // If root is NULL, the next element of the last tree is returned. void *nextTreeData(TreeNode *root) { static StackNode *iteratorStack = NULL; TreeNode *currentNode = NULL; void *data = NULL; if (root != NULL) { clearStack(iteratorStack); iteratorStack = NULL; iteratorStack = pushLeftPath(iteratorStack, root); } currentNode = (TreeNode *)top(iteratorStack); if (currentNode == NULL) { clearStack(iteratorStack); iteratorStack = NULL; return NULL; } iteratorStack = pop(iteratorStack); data = currentNode->data; iteratorStack = pushLeftPath(iteratorStack, currentNode->right); return data; } // Releases all memory resources, including the copied data in each tree node. void clearTree(TreeNode *root) { if (root != NULL) { clearTree(root->left); clearTree(root->right); free(root->data); free(root); } } // Returns the number of entries in the tree given by root. unsigned int treeSize(const TreeNode *root) { if (root == NULL) { return 0; } return 1 + treeSize(root->left) + treeSize(root->right); }