cmkl/spring-2025/sen-107/00020/lab.c

244 lines
4.7 KiB
C

/* matrilineal
*
* Build a simple, non-sorted tree of mother-daughter relationships
*
* Created by Nunthatinn Veerapaiboon, 30 Jan 2025
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* 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);
}
}
}