From c2068d6874839906c3f42d2981df60cada294d41 Mon Sep 17 00:00:00 2001 From: cdez Date: Sun, 29 Oct 2023 15:07:29 -0700 Subject: [PATCH] Unfortunate Stopping Point +- RedBlackTreeUtility.c ++ PA08_Main --- PA08-1101/PA08_Main | Bin 0 -> 33072 bytes PA08-1101/RedBlackTreeUtility.c | 609 +++++++++++++++++++++++++++++++- 2 files changed, 608 insertions(+), 1 deletion(-) create mode 100755 PA08-1101/PA08_Main diff --git a/PA08-1101/PA08_Main b/PA08-1101/PA08_Main new file mode 100755 index 0000000000000000000000000000000000000000..2a663c2c06741405bba2f7ce3247cd3c969d7d48 GIT binary patch literal 33072 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 g20lyX*plKu0WIO)S^xk5 literal 0 HcmV?d00001 diff --git a/PA08-1101/RedBlackTreeUtility.c b/PA08-1101/RedBlackTreeUtility.c index f4fa8f0..d064cb2 100644 --- a/PA08-1101/RedBlackTreeUtility.c +++ b/PA08-1101/RedBlackTreeUtility.c @@ -6,9 +6,616 @@ const char SEMICOLON_BREAK[] = "; "; const char THICK_DIVIDER = '='; const char THIN_DIVIDER = '-'; +/* Data Structures +typedef struct RedBlackNodeStruct + { + Colors color; (typedef enum { BLACK = 66, RED = 82 } Colors;) + + char data; + + struct RedBlackNodeStruct *parentPtr, *leftChildPtr, *rightChildPtr; + + } RedBlackNodeType; + +typedef enum { PREORDER_TRAVERSE = 101, INORDER_TRAVERSE = 102, + POSTORDER_TRAVERSE = 103, NODE_COLOR = 191, + NODE_DATA = 192 } ControlCodes; +Data Structures */ + // functions -// TODO: Set functions here +/* +Name: clearTree +Process: recursively returns dynamically allocated data to the OS + using a post order traversal strategy +Function input/parameters: working pointer for recursion (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: empty tree (NULL) +Device input/---: none +Device output/---: none +Dependencies: free +*/ +RedBlackNodeType *clearTree(RedBlackNodeType *localPtr) +{ + // recurse through the left children + if (localPtr->leftChildPtr != NULL) + { + clearTree(localPtr->leftChildPtr); + } + // recurse through the right children + if (localPtr->rightChildPtr != NULL) + { + clearTree(localPtr->rightChildPtr); + } + // otherwise, free the local pointer if at end of getting to bottom tree + free(localPtr); + // return NULL since no tree left + return NULL; +} + +/* +Name: copyTree +Process: copies a Red Black tree from another Red Black tree + using a pre order traversal strategy, + appropriately links child parent pointers to current node +Function input/parameters: pointer to source node (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to destination node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: createNodeFromNode, copyTree (recursively) +*/ +RedBlackNodeType *copyTree(RedBlackNodeType *srcPtr) +{ + // make a storage pointer + RedBlackNodeType *copyPtr = NULL; + // check for not equal to null + if (srcPtr != NULL) + { + // create the pointer given data + copyPtr = createNodeFromNode(srcPtr); + // recurse left child + copyPtr->leftChildPtr = copyTree(srcPtr->leftChildPtr); + // recurse right child + copyPtr->rightChildPtr = copyTree(srcPtr->rightChildPtr); + } + // return copyPtr + return copyPtr; +} + +/* +Name: createNodeFromData +Process: creates a Red Black tree node from the node data given, + all links are set to NULL +Function input/parameters: data (char), color (int) +Function output/parameters: none +Function output/returned: pointer to created node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: malloc +*/ +RedBlackNodeType *createNodeFromData(char data, int nodeColor) +{ + // define a new node + RedBlackNodeType *newNode; + // allocate memory for the newNode (RedBlackNodeType) + newNode = malloc(sizeof(RedBlackNodeType)); + // define the color as the new node's color + newNode->color = nodeColor; + // define the data of the new node to be the input data + newNode->data = data; + // set the node's pointers according to spec + newNode->parentPtr = NULL; + newNode->leftChildPtr = NULL; + newNode->rightChildPtr = NULL; + // return the created node + return newNode; +} + +/* +Name: createNodeFromNode +Process: allocates memory for node, + copies an individual tree node from another node, + all links are set to NULL +Function input/parameters: pointer to source node (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to destination node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: one line of code - createNodeFromData +*/ +RedBlackNodeType *createNodeFromNode(RedBlackNodeType *srcPtr) +{ + // return the created node from the given data + return createNodeFromData(srcPtr->data, srcPtr->color); +} + +/* +Name: displayInOrder +Process: traverses across tree, prints semicolon-delimited list, + displays "data / color" using in order strategy +Function input/parameters: pointer to current working node (RedBlackNodeType *), + pointer to row start flag + for first line of output (bool *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: printf, displayInOrder (recursively) +*/ +void displayInOrder(RedBlackNodeType *wkgPtr, bool *rowStartFlag) +{ + // check to see if the working pointer is null + if (wkgPtr != NULL) + { + // check to see if the rowStartFlag is true + if(rowStartFlag) + { + // if true, print the order + printf("Inorder : "); + // set the rowStartFlag to false + rowStartFlag = false; + } + // recurse to left node in tree + displayInOrder(wkgPtr->leftChildPtr, rowStartFlag); + // print out the string + printf(" %c/%c%s", wkgPtr->data, wkgPtr->color, SEMICOLON_BREAK); + // recurse to right node in tree + displayInOrder(wkgPtr->rightChildPtr, rowStartFlag); + } + // no return, void. +} + +/* +Name: displayPostOrder +Process: traverses across tree, prints semicolon-delimited list, + displays "data / color" using post order strategy +Function input/parameters: pointer to current working node (RedBlackNodeType *), + pointer to row start flag + for first line of output (bool *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: printf, displayPostOrder (recursively) +*/ +void displayPostOrder(RedBlackNodeType *wkgPtr, bool *rowStartFlag) +{ + // check to see if the working pointer is null + if (wkgPtr != NULL) + { + // check to see if the rowStartFlag is true + if (rowStartFlag) + { + // if true, print the order + printf("Postorder: "); + // set the rowStartFlag to false + rowStartFlag = false; + } + // recurse to left node in tree + displayPostOrder(wkgPtr->leftChildPtr, rowStartFlag); + // recurse to right node in tree + displayPostOrder(wkgPtr->rightChildPtr, rowStartFlag); + // print out the string + printf(" %c/%c%s", wkgPtr->data, wkgPtr->color, SEMICOLON_BREAK); + } + // no return, void. +} + +/* +Name: displayPreOrder +Process: traverses across tree, prints semicolon-delimited list, + displays "data / color" using pre order strategy +Function input/parameters: pointer to current working node (RedBlackNodeType *), + pointer to row start flag + for first line of output (bool *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: printf, displayPreOrder (recursively) +*/ +void displayPreOrder(RedBlackNodeType *wkgPtr, bool *rowStartFlag) +{ + // check to see if the working pointer is null + if (wkgPtr != NULL) + { + // check to see if the rowStartFlag is true + if (rowStartFlag) + { + // if true, print the order + printf("Preorder : "); + // set the rowStartFlag to false + rowStartFlag = false; + } + // print out the string + printf(" %c/%c%s", wkgPtr->data, wkgPtr->color, SEMICOLON_BREAK); + // recurse to left node in tree + displayPreOrder(wkgPtr->leftChildPtr, rowStartFlag); + // recurse to right node in tree + displayPreOrder(wkgPtr->rightChildPtr, rowStartFlag); + } + // no return, void. +} + +/* +Name: displayTree +Process: controller function for calling appropriate tree traversal +Function input/parameters: pointer to current tree root (RedBlackNodeType *), + control codes INORDER_TRAVERSE, POSTORDER_TRAVERSE, + PREORDER_TRAVERSE +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: displayed as specified +Dependencies: displayInOrder, displayPostOrder, displayPreOrder, printf +*/ +void displayTree(RedBlackNodeType *rootPtr, ControlCodes traverseCode) +{ + bool rowStarter = true; + // check to see which ControlCode was used, display based on this. + if(traverseCode == PREORDER_TRAVERSE) + { + printf("\n"); + // use the preorder traversal function + displayPreOrder(rootPtr, &rowStarter); + printf("\n"); + } + else if(traverseCode == INORDER_TRAVERSE) + { + printf("\n"); + // use the in order traversal function + displayInOrder(rootPtr, &rowStarter); + printf("\n"); + } + else + { + printf("\n"); + // use the postorder traversal function + displayPostOrder(rootPtr, &rowStarter); + printf("\n"); + } + // no return, void. +} + +/* +Name: findTreeHeight +Process: recursively finds height of tree +Function input/parameters: working pointer for recursion (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: height of tree (int) +Device input/---: none +Device output/---: none +Dependencies: getMax +*/ +int findTreeHeight(RedBlackNodeType *localPtr) +{ + // check to see if at null + if(localPtr == NULL) + { + // return negative one since either empty or at bottom of tree + return -1; + } + else + { + // traverse the left and right subtrees + int leftTreeSize = findTreeHeight(localPtr->leftChildPtr); + int rightTreeSize = findTreeHeight(localPtr->rightChildPtr); + // return the max of the subtrees, add one for the local node + return getMax(leftTreeSize, rightTreeSize) + 1; + } +} + +/* +Name: initializeRBT +Process: returns NULL to tree root pointer to prepare tree for use +Function input/parameters: none +Function output/parameters: none +Function output/returned: NULL +Device input/---: none +Device output/---: none +Dependencies: none +*/ +RedBlackNodeType *initializeRBT() +{ + // return NULL to begin tree + return NULL; +} + +/* +Name: insert +Process: sets first node if tree is empty, otherwise calls helper + to set nodes, then calls RBT resolver to rebalance tree + if node is successfully inserted by helper, + prints inserting/resolving statement and root color set to black +Function input/parameters: tree root pointer (RedBlackNodeType *), + data to be inserted (char) +Function output/parameters: none +Function output/returned: pointer to updated tree root (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: printf, createNodeFromData, insertHelper, resolveRBT +*/ +RedBlackNodeType *insert(RedBlackNodeType *treeRoot, char inData) +{ + RedBlackNodeType *insertedNode; + // check if not null + if(treeRoot != NULL) + { + // use insertHelper to get to where the data needs to go + insertedNode = insertHelper(treeRoot, inData); + // print out what data is being added, tell user being resolved + printf("\nInserting %c and resolving\n", inData); + // use resolveRBT to get the tree balanced correctly + resolveRBT(&treeRoot, insertedNode); + } + else + { + // if inserting the root node + // set the root with createNodeFromData, node is black. + treeRoot = createNodeFromData(inData, BLACK); + // tell the user inserting the data + printf("\nInserting %c and resolving\n", inData); + // tell the user that the root was set, and is black. + printf(" - Root color set to black\n"); + /* AN ALTERNATIVE COULD BE TO INSTEAD + USE THE RESOLVE FUNCTION INSTEAD OF DOING IT BY HAND*/ + } + // return treeRoot + return treeRoot; +} + +/* +Name: insertHelper +Process: recursively finds place to add node, + places node using "look down" strategy, + returns newly inserted node pointer, + if duplicated nodes/keys attempted, returns NULL +Function input/parameters: working pointer for recursion (RedBlackNodeType *), + data to be inserted (char) +Function output/parameters: none +Function output/returned: pointer to inserted node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: createNodeFromData, insertHelper (recursively) +*/ +RedBlackNodeType *insertHelper(RedBlackNodeType *wkgPtr, char inData) +{ + // compare between current node and inData + int diffChar = inData - wkgPtr->data; + + // check for moving left (diffChar < 0) + if(diffChar < 0) + { + // check for left child NULL + if(wkgPtr->leftChildPtr == NULL) + { + // assign current left child to a new node + wkgPtr->leftChildPtr = createNodeFromData(inData, RED); + // return pointer to the node added + return wkgPtr->leftChildPtr; + } + // return recursion + return insertHelper(wkgPtr->leftChildPtr, inData); + } + + // otherwise, check for moving right (diffChar > 0) + else if(diffChar > 0) + { + // check for right child NULL + if(wkgPtr->rightChildPtr == NULL) + { + // assign current right child to a new node + wkgPtr->rightChildPtr = createNodeFromData(inData, RED); + // return pointer to the node added + return wkgPtr->rightChildPtr; + } + // return recursion + return insertHelper(wkgPtr->rightChildPtr, inData); + } + + // otherwise, there is a duplicate + else + { + // return NULL + return NULL; + } +} + +/* +Name: isEmpty +Process: returns true if tree is empty, false otherwise +Function input/parameters: tree root pointer (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: result of test (bool) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +bool isEmpty(RedBlackNodeType *localPtr) +{ + // return test of root pointer is NULL + return localPtr == NULL; +} + +/* +Name: resolveRBT +Process: recursively checks tree for need to rebalance, + conducts rebalance as needed +Function input/parameters: address of tree root pointer (RedBlackNodeType **), + working pointer for recursion + which starts at the location + of the inserted node (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: none +Device input/---: none +Device output/---: none +Dependencies: printf, rotateLeft, rotateRight, swapColors, + displayTreeStructure, displayDivider +*/ +void resolveRBT(RedBlackNodeType **treeRoot, RedBlackNodeType *wkgPtr) +{ + // declare parPtr, grndParPtr, unclePtr, grtGrndPtr + RedBlackNodeType *wkgParentPtr; + RedBlackNodeType *wkgGrandParentPtr; + RedBlackNodeType *wkgUnclePtr; + RedBlackNodeType *wkgGreatGrandParentPtr; + // check for parent and grandparent exists + if(wkgPtr->parentPtr != NULL && wkgPtr->parentPtr->parentPtr != NULL) + { + // set all my relatives, will need to know which child I am + wkgParentPtr = wkgPtr->parentPtr; + wkgGrandParentPtr = wkgParentPtr->parentPtr; + if (wkgParentPtr->leftChildPtr->data == wkgPtr->data) + { + // set the uncle pointer to the parent's right child + wkgUnclePtr = wkgParentPtr->rightChildPtr; + } + else + { + // set the uncle pointer to the parent's left child + wkgUnclePtr = wkgParentPtr->leftChildPtr; + } + wkgGreatGrandParentPtr = wkgGrandParentPtr->parentPtr; + // check for red uncle + if(wkgUnclePtr != NULL && wkgUnclePtr->color == RED) + { + // change parent and uncle to black + wkgParentPtr->color = BLACK; + wkgUnclePtr->color = BLACK; + // change grandparent to red + wkgGrandParentPtr->color = RED; + // recurse with the grandparent + resolveRBT(treeRoot, wkgGrandParentPtr); + } + // otherwise, assume uncle is black + else + { + // check for parent is left of grandparent + if(wkgGrandParentPtr->leftChildPtr->data == wkgParentPtr->data) + { + // check for child is left of parent (Left Left case) + if(wkgParentPtr->leftChildPtr->data == wkgPtr->data) + { + printf("\nLL Case, rotate right\n"); + // use rotate right with grandparent(old) and parent(new) + // link the parent to grandparent's parent + // swap colors called with parent and grandparent + } + // check for child is right of parent (Left Right case) + if(wkgParentPtr->rightChildPtr->data == wkgPtr->data) + { + printf("\nLR Case, rotate right, recurse\n"); + // use rotate right with parent(old) and createdNode(new) + // call resolveRBT with parent as createdNode (will treat as LLC) + } + } + // check for parent is right of grandparent + if(wkgGrandParentPtr->rightChildPtr->data == wkgParentPtr->data) + { + // check for child is right of parent (Right Right case) + if(wkgParentPtr->rightChildPtr->data == wkgPtr->data) + { + printf("\nRR Case, rotate left\n"); + // use rotate left with grandparent(old) and parent(new) + // link the parent to grandparent's parent + // swap colors called with parent and grandparent + } + // check for child is left of parent (Right Left case) + if(wkgParentPtr->leftChildPtr->data == wkgPtr->data) + { + printf("\nRL Case, rotate left, recurse\n"); + // use rotate left with parent(old) and createdNode(new) + // call resolveRBT with parent as createdNode (will treat as RRC) + } + } + } + // end of par/gpr test + } + // check for current node is root pointer + if(wkgPtr == *treeRoot) + { + // paint it black + wkgPtr->color = BLACK; + } + // no return, void. +} + +/* +Name: rotateLeft +Process: "rotates" nodes to the left by resetting pointers + to related nodes +Function input/parameters: old and new top node pointers (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to new top node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +RedBlackNodeType *rotateLeft(RedBlackNodeType *newTopPtr, + RedBlackNodeType *oldTopPtr) +{ + // set the old top's parent's right child to the new top + oldTopPtr->parentPtr->rightChildPtr = newTopPtr; + // set the old top's right child to the new top's left child + oldTopPtr->rightChildPtr = newTopPtr->leftChildPtr; + // set the new top's parent to old top's parent + newTopPtr->parentPtr = oldTopPtr->parentPtr; + // set the new top's left child to old top + newTopPtr->leftChildPtr = oldTopPtr; + // set the old top's parent to new top + oldTopPtr->parentPtr = newTopPtr; + // return new top + return newTopPtr; +} + +/* +Name: rotateRight +Process: "rotates" nodes to the right by resetting pointers + to related nodes +Function input/parameters: old and new top node pointers (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: pointer to new top node (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +RedBlackNodeType *rotateRight(RedBlackNodeType *newTopPtr, + RedBlackNodeType *oldTopPtr) +{ + // set the old top's parent's left child to the new top + oldTopPtr->parentPtr->leftChildPtr = newTopPtr; + // set the old top's left child to the new top's right child + oldTopPtr->leftChildPtr = newTopPtr->rightChildPtr; + // set the new top's parent to old top's parent + newTopPtr->parentPtr = oldTopPtr->parentPtr; + // set the new top's right child to old top + newTopPtr->rightChildPtr = oldTopPtr; + // set the old top's parent to new top + oldTopPtr->parentPtr = newTopPtr; + // return new top + return newTopPtr; +} + +/* +Name: swapColors +Process: swaps or exchanges colors between two nodes +Function input/parameters: pointers to two nodes (RedBlackNodeType *) +Function output/parameters: none +Function output/returned: updated pointers to two nodes (RedBlackNodeType *) +Device input/---: none +Device output/---: none +Dependencies: none +*/ +void swapColors(RedBlackNodeType *one, RedBlackNodeType *other) +{ + // define temporary holding place for one color + int tempColor = one->color; + // swap the colors using the temp. + one->color = other->color; + other->color = tempColor; + // no return, void. +} //////////////////////////////////////////////////////////////////////////////// // No student coding below this point