/* matrilineal.c * * A non-sorted tree of mother-daughter relationships * * Created by Pasin Manurangsi, 2025-01-08 * Modified by Thanawin Pattanaphol, 2025-05-02 * */ #include #include #include /* Adds person with a given name at the root */ #define MAX_CHILDREN 10 #define MAX_NAME_LENGTH 25 #define MAX_PATH_LENGTH 100 typedef struct NODE_T { char name[MAX_NAME_LENGTH]; int numChildren; struct NODE_T* parent; struct NODE_T* children[MAX_CHILDREN]; } NODE_T; NODE_T* root = NULL; NODE_T* createNode(char* name) { NODE_T* newNode = (NODE_T*)malloc(sizeof(NODE_T)); if (newNode == NULL) { printf("Memory allocation failed.\n"); exit(1); } strncpy(newNode->name, name, MAX_NAME_LENGTH - 1); newNode->name[MAX_NAME_LENGTH - 1] = '\0'; newNode->numChildren = 0; newNode->parent = NULL; for (int i = 0; i < MAX_CHILDREN; i++) { newNode->children[i] = NULL; } printf("Added\n"); return newNode; } // Create the root NODE_T* addRoot(char* name) { if (root != NULL) { printf("Root already exists.\n"); return root; } root = createNode(name); return root; } // Function that helps finding a node by name NODE_T* findNode(NODE_T* currentNode, char* name) { if (currentNode == NULL) return NULL; if (strcmp(currentNode->name, name) == 0) return currentNode; for (int i = 0; i < currentNode->numChildren; i++) { NODE_T* found = findNode(currentNode->children[i], name); if (found != NULL) return found; } return NULL; } /* Adds person with a given name and mother's name to the tree. */ NODE_T* addNonRoot(char* name, char* motherName) { if (root == NULL) { printf("Error: Root does not exist. Please add a root first.\n"); return NULL; } NODE_T* motherNode = findNode(root, motherName); if (motherNode == NULL) { printf("Unsuccessful\n"); return NULL; } if (motherNode->numChildren == MAX_CHILDREN) { printf("Unsuccessful\n"); return NULL; } NODE_T* newNode = createNode(name); newNode->parent = motherNode; motherNode->children[motherNode->numChildren++] = newNode; return newNode; } /* DFS function */ void dfsPrintDescendants(NODE_T* node) { for (int i = 0; i < node->numChildren; i++) { printf("%s ", node->children[i]->name); dfsPrintDescendants(node->children[i]); } } /* Prints the descendants of a given node. */ void printDescendants(char* name) { NODE_T* node = findNode(root, name); if (node == NULL || node->numChildren == 0) { printf("Not Found\n"); return; } dfsPrintDescendants(node); printf("\n"); } /* DFS function to find the maximum chain */ void dfsFindMaxChain( NODE_T* node, NODE_T* path[], int depth, NODE_T* maxPath[], int* maxDepth ) { path[depth] = node; if (node->numChildren == 0) { if (depth + 1 > *maxDepth) { *maxDepth = depth + 1; for (int i = 0; i <= depth; i++) { maxPath[i] = path[i]; } } } else { for (int i = 0; i < node->numChildren; i++) { dfsFindMaxChain( node->children[i], path, depth + 1, maxPath, maxDepth ); } } } // Function to print the longest chain void printLongestChain() { if (root == NULL) { printf("Tree is empty\n"); return; } NODE_T* path[MAX_PATH_LENGTH]; NODE_T* maxPath[MAX_PATH_LENGTH]; int maxDepth = 0; dfsFindMaxChain(root, path, 0, maxPath, &maxDepth); for (int i = 0; i < maxDepth; i++) { printf("%s ", maxPath[i]->name); } printf("\n"); } int main() { char input[64]; char name[MAX_NAME_LENGTH]; char motherName[MAX_NAME_LENGTH]; int numOperations; scanf("%d", &numOperations); scanf("%s", name); addRoot(name); for (int i = 1; i < numOperations; i++) { scanf("%s", input); if (strcmp(input, "Add") == 0) { scanf("%s %s", name, motherName); addNonRoot(name, motherName); } else if (strcmp(input, "Descendant") == 0) { scanf("%s", name); printDescendants(name); } else if (strcmp(input, "Max") == 0) { printLongestChain(); } } return 0; }