/* orgChart * * Build a corporate hierarchy structure and sorted binary tree * * Created by Chavakorn Arunkunarax and Phasit Thanitkul, 2025-01-12 * Modified by Thanawin Pattanaphol, 2025-05-02 */ #include #include #include #include // Structure for an employee in the organization chart (general tree node) typedef struct EmployeeNode { char name[32]; char employeeId[8]; char jobTitle[32]; struct EmployeeNode *supervisor; struct EmployeeNode *firstChild; struct EmployeeNode *nextSibling; } EmployeeNode; // Structure for a node in the sorted binary tree (index) typedef struct IndexNode { char key[40]; // Concatenation of Name and EmployeeId EmployeeNode *employeePtr; struct IndexNode *left; struct IndexNode *right; } IndexNode; EmployeeNode *root = NULL; // Root of the organization chart IndexNode *indexRoot = NULL; // Root of the sorted binary tree // Function to create a new employee node EmployeeNode *createEmployeeNode(char *name, char *employeeId, char *jobTitle) { EmployeeNode *newNode = (EmployeeNode *)malloc(sizeof(EmployeeNode)); if (newNode == NULL) { perror("Failed to allocate memory for employee node"); exit(EXIT_FAILURE); } strcpy(newNode->name, name); strcpy(newNode->employeeId, employeeId); strcpy(newNode->jobTitle, jobTitle); newNode->supervisor = NULL; newNode->firstChild = NULL; newNode->nextSibling = NULL; return newNode; } // Function to create a new index node IndexNode *createIndexNode(char *key, EmployeeNode *employeePtr) { IndexNode *newNode = (IndexNode *)malloc(sizeof(IndexNode)); if (newNode == NULL) { perror("Failed to allocate memory for index node"); exit(EXIT_FAILURE); } strcpy(newNode->key, key); newNode->employeePtr = employeePtr; newNode->left = NULL; newNode->right = NULL; return newNode; } // Function to insert into the sorted binary tree IndexNode *insertIndexNode(IndexNode *root, char *key, EmployeeNode *employeePtr) { if (root == NULL) { return createIndexNode(key, employeePtr); } int cmp = strcmp(key, root->key); if (cmp < 0) { root->left = insertIndexNode(root->left, key, employeePtr); } else if (cmp > 0) { root->right = insertIndexNode(root->right, key, employeePtr); } return root; } /* Adds employee to the corporate hierarchy structure and sorted binary tree */ void addEmployee(char *name, char *employeeId, char *jobTitle, char *supervisorName, char *supervisorId) { EmployeeNode *newEmployee = createEmployeeNode(name, employeeId, jobTitle); char indexKey[40]; sprintf(indexKey, "%s%s", name, employeeId); indexRoot = insertIndexNode(indexRoot, indexKey, newEmployee); if (strcmp(supervisorName, "--") == 0) { if (root == NULL) { root = newEmployee; } else { fprintf(stderr, "Error: Multiple root employees found.\n"); // Handle this error as needed, maybe free the newEmployee } return; } EmployeeNode *supervisorNode = NULL; // Search for the supervisor in the existing organization chart // A simple linear search here. For larger organizations, a hash map would be more efficient. // However, for this exercise, we'll keep it straightforward. EmployeeNode *queue[100]; // Assuming a reasonable maximum number of employees for the queue int head = 0, tail = 0; if (root != NULL) { queue[tail++] = root; } while (head < tail) { EmployeeNode *current = queue[head++]; if (strcmp(current->name, supervisorName) == 0 && strcmp(current->employeeId, supervisorId) == 0) { supervisorNode = current; break; } EmployeeNode *child = current->firstChild; while (child != NULL) { queue[tail++] = child; child = child->nextSibling; } } if (supervisorNode != NULL) { newEmployee->supervisor = supervisorNode; if (supervisorNode->firstChild == NULL) { supervisorNode->firstChild = newEmployee; } else { EmployeeNode *sibling = supervisorNode->firstChild; while (sibling->nextSibling != NULL) { sibling = sibling->nextSibling; } sibling->nextSibling = newEmployee; } } else { fprintf(stderr, "cannot_add %s %s\n", name, employeeId); // Free the allocated memory for the employee node since it couldn't be added free(newEmployee); } } /* Prints the corporate hierarchy structure, pre-order */ void printCorporateHierarchyHelper(EmployeeNode *node, int level) { if (node == NULL) { return; } for (int i = 0; i < level; i++) { printf("..."); } printf("%s %s %s\n", node->name, node->employeeId, node->jobTitle); EmployeeNode *child = node->firstChild; while (child != NULL) { printCorporateHierarchyHelper(child, level + 1); child = child->nextSibling; } } void printCorporateHierarchy() { printCorporateHierarchyHelper(root, 0); } // Helper function for in-order traversal of the index tree to print sorted list void printSortedListHelper(IndexNode *root) { if (root == NULL) { return; } printSortedListHelper(root->left); printf("%s %s %s\n", root->employeePtr->name, root->employeePtr->employeeId, root->employeePtr->jobTitle); printSortedListHelper(root->right); } /* Prints the sorted list of employees */ void printSortedList() { printSortedListHelper(indexRoot); } /* Searches for an employee in the corporate hierarchy structure using the index tree */ void searchEmployee(char *name, char *employeeId) { char searchKey[40]; sprintf(searchKey, "%s%s", name, employeeId); IndexNode *current = indexRoot; while (current != NULL) { int cmp = strcmp(searchKey, current->key); if (cmp < 0) { current = current->left; } else if (cmp > 0) { current = current->right; } else { EmployeeNode *employee = current->employeePtr; printf("%s %s %s\n", employee->jobTitle, employee->supervisor ? employee->supervisor->name : "Top", employee->employeeId); return; } } printf("not_found\n"); } // Helper function to free the organization chart tree void freeOrganizationChart(EmployeeNode *node) { if (node == NULL) { return; } EmployeeNode *child = node->firstChild; while (child != NULL) { EmployeeNode *next = child->nextSibling; freeOrganizationChart(child); child = next; } free(node); } // Helper function to free the index tree void freeIndexTree(IndexNode *node) { if (node == NULL) { return; } freeIndexTree(node->left); freeIndexTree(node->right); free(node); } /* Free the contents of the datastructures used */ void freeAll() { freeOrganizationChart(root); freeIndexTree(indexRoot); root = NULL; indexRoot = NULL; } int main() { char input[128]; char name[32]; char employeeId[8]; char jobTitle[32]; char supervisorName[32]; char supervisorId[8]; int numEmployees; int numQuestions; if (scanf("%d", &numEmployees) != 1) { fprintf(stderr, "Error reading number of employees.\n"); return 1; } if (scanf("%d", &numQuestions) != 1) { fprintf(stderr, "Error reading number of queries.\n"); return 1; } for (int i = 0; i < numEmployees; i++) { if (scanf("%s %s %s %s %s", name, employeeId, jobTitle, supervisorName, supervisorId) != 5) { fprintf(stderr, "Error reading employee data.\n"); return 1; } addEmployee(name, employeeId, jobTitle, supervisorName, supervisorId); } printCorporateHierarchy(); for (int i = 0; i < numQuestions; i++) { if (scanf("%s %s", name, employeeId) != 2) { fprintf(stderr, "Error reading query.\n"); return 1; } searchEmployee(name, employeeId); } printSortedList(); freeAll(); return 0; }