NodeT *insertT(NodeT *pRoot,Element value,char szSubId[]) { // p contains the root's ID NodeT *p = findId(pRoot,szSubId); if (p == NULL) return NULL; //if child is not null, traverses sibling chain until null is found if (p->pChild != NULL) { p = p->pChild; while (p->pSibling != NULL) p = p->pSibling; //sticks node on the end of the sibling chain p->pSibling = allocateNodeT(value); return p->pSibling; } //parent node is found and child is empty else { p->pChild = allocateNodeT(value); return p->pChild; } return NULL; }
/******************** insertT **************************************** NodeT *insertT(NodeT **pp, Element element) Purpose: Inserts into the quote tree at the requested location using double pointer notation. If location is NULL, allocates memory. Parameters: I/O NodeT **pp Pointer to a pointer of the location to be inserted I Element element Item to be inserted into the tree Returns: pp Returns a pointer to the node's new position Notes: **************************************************************************/ NodeT *insertT(NodeT **pp, Element element) { // if the ID's match, return the node if (*pp == NULL) { *pp = allocateNodeT(element); return *pp; } else { return insertT(&(*pp)->pSibling,element); } }
// Puts integers (iKey) into the binary tree & updates the iCount integers NodeT *insertT(NodeT *p, int iKey) { if (p == NULL) return allocateNodeT(iKey); if (iKey == p->iKey) { return p; } else if (iKey < p->iKey) { p->iCount++; p->pLeft = insertT(p->pLeft, iKey); } else { p->pRight = insertT(p->pRight, iKey); } return p; }
/********************************* processCommand ******************************* void processCommand(Tree tree, QuoteSelection quoteSelection, char *pszInput) Purpose: to read input file and Parameters: Returns: ********************************************************************************/ void processCommand(Tree tree, QuoteSelection quoteSelection, char *pszInput) { char szToken[MAX_TOKEN_SIZE+1]; char szSubordinateToId[MAX_ID_SIZE]; char szOptionId[MAX_ID_SIZE]; NodeT *p; Element element; //Gets first word in input pszInput = getToken(pszInput,szToken,MAX_TOKEN_SIZE); //Set of if statmenets to check the command if (strcmp(szToken,"DEFINE")==0) { //checks the next word after the command pszInput = getToken(pszInput,szToken,MAX_TOKEN_SIZE); //check to see if it is OPTION or VALUE if (strcmp(szToken,"OPTION")==0) { element.cNodeType = 'O'; sscanf(pszInput, "%s %s %[^\t\n]" ,element.szId ,szSubordinateToId ,element.szTitle); //check to see if it is root node if (strcmp(szSubordinateToId,"ROOT")==0) { if (tree->pRoot == NULL) tree->pRoot = allocateNodeT(element); else tree->pRoot->pSibling = allocateNodeT(element); } else { insertPriceMenu(tree,element,szSubordinateToId); } } else if (strcmp(szToken,"VALUE")==0) { element.cNodeType = 'V'; sscanf(pszInput, "%s %s %s %lf %[^\t\n]" ,element.szId ,szOptionId ,&element.cCostInd ,&element.dCost ,element.szTitle); if (strcmp(szOptionId,"ROOT")==0) printf("DEFINE ERROR: ROOT is not option\n"); else insertPriceMenu(tree,element,szOptionId); } } else if (strcmp(szToken,"PRINT")==0) { pszInput = getToken(pszInput,szToken,MAX_TOKEN_SIZE); //if the command is to print all if (strcmp(szToken,"ALL")==0) { //Pretty print printPriceMenu(tree); } //if the command is print one else { pszInput = getToken(pszInput,szToken,MAX_TOKEN_SIZE); printOne(tree, szToken); } } else if (strcmp(szToken,"QUOTE")==0) { //3 cases, BEGIN, OPTION,END pszInput = getToken(pszInput,szToken,MAX_TOKEN_SIZE); if (strcmp(szToken,"BEGIN")==0) { quoteSelection->iQuoteItemCnt = 0; } if (strcmp(szToken,"OPTION")==0) { sscanf(pszInput," %d %s %d" ,"eSelection->quoteItemM[quoteSelection->iQuoteItemCnt].iLevel ,quoteSelection->quoteItemM[quoteSelection->iQuoteItemCnt].szOptionId ,"eSelection->quoteItemM[quoteSelection->iQuoteItemCnt].iSelection); quoteSelection->iQuoteItemCnt++; } if (strcmp(szToken,"END")==0) { QuoteResult result; result = determineQuote(tree,quoteSelection); switch (result.returnCode) { case 0: printf("\t\tTotal Cost \t\t\t\t$%.2lf\n",result.dTotalCost); break; case 1: printf("\tPartial Total is \t\t\t\t$%.2lf\n",result.dTotalCost); printf("PARTIAL QUOTE: missing %s", result.error.szOptionId); break; case 2: printf("Bad option value: %s\n" ,result.error.szOptionId); break; case 3: printf("Bad Selection value: %s %d\n" ,result.error.szOptionId ,result.error.iSelection); break; } } } else if (strcmp(szToken,"DELETE")==0) { pszInput = getToken(pszInput,szToken,MAX_TOKEN_SIZE); p = findId(tree->pRoot,szToken); if (p == NULL) printf("DELETE ERROR: Id %s not found\n",szToken); else { deleteItem(tree,szToken); } } }
int main() { // Variables for diagnosis tree NodeT *root = NULL; // Variables for text List TextEntry text; TextList textList = newTextList(); // Variables for driver input control char szInputBuffer[MAX_LINE_SIZE+1]; // input command line int iScanfCnt; // sscanf return char *pszRemaining; // getToken returns this Token szCommand; // Input Command //Variables for reading data input command arguments Element element; // Binary Tree element char szParentId[MAX_ID_SIZE + 1]; // parent Id for NODE command char cYN; // Y or N value for NODE command char szAnswers[MAX_NUMBER_ANSWERS]; // Text for answers // Variables for results char *pszResultId; // Result of searchT or help // Read command lines until EOF while (fgets(szInputBuffer, MAX_LINE_SIZE, stdin) != NULL) { printf("%s", szInputBuffer); // If the line is just a comment, ignore it if (szInputBuffer[0] == '*') continue; // Command is a comment so skip it // get the command pszRemaining = getToken(szInputBuffer, szCommand, MAX_TOKEN_SIZE); // Determine what to invoke based on the command if (strcmp(szCommand, "ROOT") == 0) { // ROOT id - create the root for the tree pszRemaining = getToken(pszRemaining, element.szId, MAX_ID_SIZE); if (pszRemaining == NULL) ErrExit(ERR_DATA, "Invalid data for ROOT command, missing ID"); element.cNodeType = 'Q'; root = allocateNodeT(element); } else if (strcmp(szCommand, "NODE") == 0) { // NODE type id parentId yn iScanfCnt = sscanf(pszRemaining, "%c %s %s %c" , &element.cNodeType, element.szId , szParentId, &cYN); if (iScanfCnt < 4) ErrExit(ERR_DATA, "Invalid data for NODE command: '%s'", pszRemaining); // insert your code to check warning cases and handle the insertion insert(root, szParentId, element, cYN); } else if (strcmp(szCommand, "TEXT") == 0) { // TEXT type id displayText iScanfCnt = sscanf(pszRemaining, "%c %s %79[^\n]", &text.cType, text.szId, text.szText); if (iScanfCnt < 3) ErrExit(ERR_DATA, "Invalid data for TEXT command: '%s'", pszRemaining); addTextEntry(textList, text); } else if (strcmp(szCommand, "PRINT") == 0) { // PRINT using your prettyPrintT routine prettyPrintT(root, 0, textList); printf("\n\n"); } else if (strcmp(szCommand, "HELP") == 0) { // HELP id answers pszRemaining = getToken(pszRemaining, szAnswers, MAX_NUMBER_ANSWERS); if (pszRemaining == NULL) ErrExit(ERR_DATA, "Invalid data for HELP command, missing answers"); pszResultId = help(root, szAnswers, 0, textList); // It is expected that help might return NULL, if the tree is // not defined properly. (not necessarily a student error) if (pszResultId == NULL) printf("\t*** Warning: NULL returned from HELP\n"); else printf("\t%s: %s\n", pszResultId , getText(textList, pszResultId)); } else if (strcmp(szCommand, "DELETE") == 0) { pszRemaining = getToken(pszRemaining, element.szId, MAX_ID_SIZE); if (pszRemaining == NULL) ErrExit(ERR_DATA, "Invalid data for DELETE command, missing ID"); // insert your code for the DELETE command which should remove the // specified ID from its parent node and also free the subtree defined by // the specified ID deleteNode(root, element.szId); } } // Your code to free the tree freeT(root); // Free the textList free(textList); printf("\n"); return 0; }