244 lines
4.7 KiB
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);
|
|
}
|
|
}
|
|
}
|