/* matrilineal * * Build a simple, non-sorted tree of mother-daughter relationships * * Created by Nunthatinn Veerapaiboon, 30 Jan 2025 */ #include #include #include /* Adds person with a given name at the root. */ #define MAX_CHILDREN 10 #define MAX_NAME_LENGTH 25 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 Root NODE_T* addRoot(char* name) { if (root != NULL) { printf("Root already exists.\n"); return root; } root = createNode(name); return root; } // Helper function to find a node by name (DFS) NODE_T* findNode(NODE_T* currentNode, char* name) { if (currentNode == NULL) { return NULL; } // Found at current node if (strcmp(currentNode->name, name) == 0) { return currentNode; } for (int i = 0; i < currentNode->numChildren; i++) { // recursively find in Children node NODE_T* found = findNode(currentNode->children[i], name); // Return node if it was found 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; } // Find mother node NODE_T* motherNode = findNode(root, motherName); if (motherNode == NULL) { printf("Not Found\n"); return NULL; } if (motherNode->numChildren == MAX_CHILDREN) { printf("Unsuccessful\n"); return NULL; } // Create new node NODE_T* newNode = createNode(name); newNode->parent = motherNode; motherNode->children[motherNode->numChildren] = newNode; motherNode->numChildren++; return newNode; } /* Prints the person's mother. */ void queryMother(char* name) { if (root == NULL) { printf("The tree is empty.\n"); return; } NODE_T* node = findNode(root, name); if (node == NULL) { printf("Not Found\n"); } else if (node->parent == NULL) { printf("Not Found\n"); } else { printf("%s", node->parent->name); } } /* Prints the person's daughters. */ void queryDaughters(char* name) { if (root == NULL) { printf("The tree is empty.\n"); return; } NODE_T* node = findNode(root, name); if (node == NULL) { printf("Not Found\n"); } else if (node->numChildren == 0) { printf("Not Found\n"); } else { for (int i = 0; i < node->numChildren; i++) { printf("%s ", node->children[i]->name); } printf("\n"); } } /* Prints the person's sisters. */ void querySisters(char* name) { if (root == NULL) { printf("The tree is empty.\n"); return; } NODE_T* node = findNode(root, name); if (node == NULL) { printf("Not Found\n"); } else if (node->parent == NULL) { printf("Not Found\n"); } else { NODE_T* motherNode = node->parent; if (motherNode->numChildren <= 1) { printf("Not Found\n"); } else { for (int i = 0; i < motherNode->numChildren; i++) { // Don't print self name if (strcmp(motherNode->children[i]->name, name) != 0) { printf("%s ", motherNode->children[i]->name); } printf("\n"); } } } } int main() { char input[64]; // Input operation name char name[MAX_NAME_LENGTH]; // The name of the woman char motherName[MAX_NAME_LENGTH]; // The number of woman's mother int numOperations; // The number of operations. scanf("%d", &numOperations); scanf("\n%s", name); NODE_T* root = addRoot(name); for (int i = 1 ; i < numOperations ; i ++) { scanf("\n%s ", input); if (strcmp(input, "Add") == 0) { scanf("%s %s", name, motherName); addNonRoot(name, motherName); } else if (strcmp(input, "Mother") == 0) { scanf("%s", name); queryMother(name); } else if (strcmp(input, "Daughters") == 0) { scanf("%s", name); queryDaughters(name); } else { scanf("%s", name); querySisters(name); } } }