Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Please solve in C language. 3.1. Delete Purpose - delete the first node/record f

ID: 3728821 • Letter: P

Question

Please solve in C language.

3.1. Delete Purpose - delete the first node/record from the list Function declaration: int deleteFromList(PersonalInfo **head, unsigned int *id, char *firstName, char *FamilyName);

3.2. Search by name and delete the node Purpose - delete the first node with the matching firstName Function declaration: int deleteNodeByName(PersonalInfo **head, char *firstName, char *FamilyName, unsigned int *id)

3.3. Delete the last node in the list Purpose - delete the last node in the list Function declaration: int deleteLast(PersonalInfo **head, unsigned int *id, char *firstName, char *FamilyName)

3.4. Delete After Purpose - delete the record after the given record Function declaration: int deleteAfter(PersonalInfo *node, unsigned int *id, char *firstName, char *FamilyName)

3.5. Delete the list and all the nodes Purpose - deletes all nodes from the list Function declaration: void deleteList(PersonalInfo **head)

------------------------------bubble_sort.h-------------------------------------

/*

File name is bubble_sort.h

Purpose: file contains a prototype for a bubble sort function

*/

#ifndef BUBBLE_SORT_2401_HEADER

#define BUBBLE_SORT_2401_HEADER 1

/************************************************************************/

// INCLUDE FILES

#include "linked_list.h"

/************************************************************************/

// FUNCTION PROTOTYPES

void bubbleSort(PersonalInfo **head);

#endif

------------------------------linked_list.c-------------------------------------

/*

File name is linked_list.c

Purpose: file contains functions for manipulating singly linked list

*/

/******************************************************************/

// INCLUDE

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

#include "linked_list.h"

/************************************************************************/

// Define

/************************************************************************/

/*

Purpose: insert a new node into the list as the first element

input

id - id of person

firstName - first name of person

familyName - family name of person

input/output

head - head of linked list

return

A pointer to the node that was allocated.  

NULL - if the operation was not successful

*/

PersonalInfo *insertToList(PersonalInfo **head, unsigned int id,

char *firstName, char *familyName)

{

// add code

//

}

/************************************************************************/

/*

Purpose: insert a new node into the list after the given node  

Input

node - the node after which the new node must be added to the list

id - id of person

firstName - first name of person

familyName - family name of person

return

A pointer to the node that was allocated.  

NULL - if the operation was not successful

*/

PersonalInfo *insertAfter(PersonalInfo *node, unsigned int id, char *firstName, char *familyName)

{

// add code

}

/************************************************************************/

/*

Purpose: create a new node and insert it into the end of the list

Input

head - the head of the list

id - id of person

firstName - first name of person

familyName - family name of person

return

A pointer to the node that was allocated.  

NULL - if the operation was not successful

*/

PersonalInfo *insertLast(PersonalInfo **head, unsigned int id, char *firstName, char *familyName)

{

// add code

}

/************************************************************************/

/*

Purpose: search for the first node with the matching firstName

Input

head - the head of the list

firstName - first name of person

return

a pointer to the node that was found.

NULL - if no node was found or list empty

*/

PersonalInfo *searchByName(PersonalInfo *head, char *firstName)

{

// add code

}

/************************************************************************/

/*

Purpose: search for the first node with the matching id

Input

head - the head of the list

id - id of person person

return

a pointer to the node that was allocated.  

NULL - if no node was found or list empty

*/

PersonalInfo *searchById(PersonalInfo *head, unsigned int id)

{

// add code

  

}

/***************************************************************/

/*

Purpose: delete the first node from the list

Input

head - the head of the list

output

head - the head of the list

firstName - first name of delted record

familyName - family name of deleted recrod

id - id of deleted record

return

0 if node was deleted

1 if node was not deleted or list is empty

*/

int deleteFromList(PersonalInfo **head, unsigned int *id,

char *firstName, char *familyName)

{

// add code

}

/***************************************************************/

/*

Purpose: delete the last node from the list

Input

head - the head of the list

output

head - the head of the list

firstName - first name of delted record

familyName - family name of deleted recrod

id - id of deleted record

return

0 if node was deleted  

1 if node was not deleted or list is empty

*/

int deleteLast(PersonalInfo **head, unsigned int *id,

char *firstName, char *familyName)

{

// add code

}

/************************************************************************/

/*

Purpose: delete the record after the given node

Input

node - a node in the list

output

firstName - first name of delted record

familyName - family name of deleted recrod

id - id of deleted record

return

0 if node was deleted

1 if node was not deleted (either input node is NULL or input node was the lastnode in the list)

*/

int deleteAfter(PersonalInfo *node, unsigned int *id,

char *firstName, char *familyName)

{

// add code

}

/************************************************************************/

/*

Purpose: delete the first node with the matching firstName

Input

head - the head of the list

firstName - first name of person

output

head - the head of the list

firstName - first name of deleted record

familyName - family name of deleted recrod

id - id of deleted record

return

0 if node was deleted

1 if node was not found (e.g., list is empty, no such node exists)

*/

int deleteNodeByName(PersonalInfo **head, char *firstName,

char *familyName, unsigned int *id)

{

// add code

}

/************************************************************************/

/*

Purpose: deletes all nodes from the list

input/output

head - the head of the list

*/

void deleteList(PersonalInfo **head)

{

// add code

}

/************************************************************************/

/*

Purpose: prints the fields of a node

input:

node - a pointer to a given node

*/

void printNode(PersonalInfo *node)

{

printf("%-20s %-20s %7d ",node->firstName, node->familyName, node->id);

}

/************************************************************************/

/*

Purpose: prints all the records in the list

input

head - the head of the list

*/

void printList(PersonalInfo *head)

{

// add code

}

/************************************************************************/

/*

Purpose: counts the number of nodes in the list

input

head - the head of the list

return

the number of nodes in the list

*/

int listSize(PersonalInfo *head)

{

// add code

}

/************************************************************************/

/*

Purpose: counts the number of nodes in the list with a matching firstName

input

head - the head of the list

return

the number of nodes in the list that match the firstName

*/

int countRecords(PersonalInfo *head, char *firstName)

{

// add code

}

/************************************************************************/

/*

Purpose: removes all duplicates records from the list. Duplicate records are determined by their first name.

You can assume that the listed is sorted by first name.

input

head - the head of the list

*/

void removeDuplicates(PersonalInfo *head)

{

// add code

}

------------------------------linked_list.h-------------------------------------

/*

File name is linked_list.h

Purpose: file contains functions for manipulating singly linked list

*/

#ifndef LINKED_LIST_2401_HEADER

#define LINKED_LIST_2401_HEADER 1

/************************************************************************/

// DEFINESD

#define NAME_LENGTH 16

/************************************************************************/

// STRUCTURES

typedef struct personalInfo {

struct personalInfo *next;

unsigned int id;

char firstName[NAME_LENGTH];

char familyName[NAME_LENGTH];

} PersonalInfo;

/************************************************************************/

// FUNCTION PROTOTYPES

// Insert Functions

PersonalInfo *insertToList(PersonalInfo **head, unsigned int id,

char *firstName, char *familyName);

PersonalInfo *insertAfter(PersonalInfo *node, unsigned int id,

char *firstName, char *familyName);

PersonalInfo *insertLast(PersonalInfo **head, unsigned int id,

char *firstName, char *familyName);

// Search Functions

PersonalInfo *searchByName(PersonalInfo *head, char *firstName);

PersonalInfo *searchById(PersonalInfo *head, unsigned int id);

// Delete Functions

int deleteFromList(PersonalInfo **head, unsigned int *id,

char *firstName, char *familyName);

int deleteLast(PersonalInfo **head, unsigned int *id,

char *firstName, char *familyName);

int deleteAfter(PersonalInfo *node, unsigned int *id,

char *firstName, char *familyName);

int deleteNodeByName(PersonalInfo **head, char *firstName,

char *lastName, unsigned int *id);

void deleteList(PersonalInfo **head);

// Print Functions

void printNode(PersonalInfo *node);

void printList(PersonalInfo *head);

// Counting Functions

int listSize(PersonalInfo *head);

int countRecords(PersonalInfo *head, char *firstName);

// Miscellaneous Functions

void removeDuplicates(PersonalInfo *head);

#endif

------------------------------main.c-------------------------------------

// FILE IS main.c

/*

Description:

This is an exmaple of a test program that you should write to test your code.  

The testing is not complete because it checks only a subset of the required functionality

and not all aspects of it.

*/

#include "stdio.h"

#include "stdlib.h"

#include "string.h"

#include "linked_list.h"

#include "bubble_sort.h"

#define CONTINUE {printf("hit to continue "); getchar();}

void populatePerson(char *firstName, char *familyName, int *id);

int main(int argc, char* argv[])

{

char firstName[NAME_LENGTH];

char familyName[NAME_LENGTH];

int id;

PersonalInfo *empHead = NULL;

PersonalInfo *p = NULL, *q = NULL;

int i;

int rc = 0;

for (i = 0; i < 20; i++) {

// add code for testing

populatePerson(firstName, familyName, &id);

insertToList(&empHead, id, firstName, familyName);

}

printList(empHead);

printf("test SearchById ");

q = p = searchById(empHead, 111);

if(p == NULL) {

printf("search by id failed ");

} else {

printNode(p);

}

CONTINUE;

if (p != NULL) {

for (i = 0; i < 4; i++) {

populatePerson(firstName, familyName, &id);

p = insertAfter(p, id, firstName, familyName);

}

}

printList(empHead);

// test delete after

  

rc = deleteAfter(q, &id, firstName, familyName);

printf("deleteAfter rc = %d ",rc);

printList(empHead);

CONTINUE;

p = searchById(empHead, 111);

if (p != NULL) {

printf(" found name to delete ");

printNode(p);

strncpy(firstName, p->firstName, NAME_LENGTH);

deleteNodeByName(&empHead, firstName, familyName, &id);

}

bubbleSort(&empHead);

printf(" sorted list ");

printList(empHead);

// getchar();

printf(" remove duplicates ");

removeDuplicates(empHead);

printList(empHead);

deleteList(&empHead);

// getchar();

return 0;

}

/***************************************************************************/

/* purpose: the function populate the personal info

input/output

struct personalInfo *p - allocated memory to the struct pointer which the function assigns values.

*/

void populatePerson(char *firstName, char *familyName, int *id)

{

static int initRand = 0;

int j;

char *first[5] = { "John", "Don", "Edna", "Bev", "Miya" };

char *family[5] = { "Broker", "Smith", "Tower", "Little", "Bronson" };

if (!initRand) {

srand(1557);

initRand ++;

}

// populate the first name using a random i ndex to the first name array

j = rand() % 5;

// copy the first name to the structure pointed by p using strcpy

strncpy(firstName, first[j], NAME_LENGTH);

// populate the first name using a random i ndex to the first name array

j = rand() % 5;

// copy the family name to the structure pointed by p using strcpy

strncpy(familyName, family[j], NAME_LENGTH);

// populate the student id using the random numnber in the range of 0-4096  

*id = rand() % 150;

}

Explanation / Answer

compile using

gcc main.c linked_list.c bubble_sort.c

The file bubble_sort.c is not present, I'm assuming you took care of it :D . The function definition of removeDuplicates had to be modified a bit. A new function NewNode is added to make the code simple.

The code was thoroughly checked without the bubble_sort file, uncomment the bubble_sort include line and the call to bubble sort in main.c to make removeDuplicates work flawlessly :D

Here are the required codes. Best regards.

P.S. : If you also need the BubbleSort.c file please comment below and I would code it for you :)

main.c

// FILE IS main.c
/*
Description:
This is an exmaple of a test program that you should write to test your code.
The testing is not complete because it checks only a subset of the required functionality
and not all aspects of it.
*/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "linked_list.h"
// #include "bubble_sort.h"
#define CONTINUE {printf("hit to continue "); getchar();}
void populatePerson(char *firstName, char *familyName, int *id);
int main(int argc, char* argv[])
{
   char firstName[NAME_LENGTH];
   char familyName[NAME_LENGTH];
   int id;
   PersonalInfo *empHead = NULL;
   PersonalInfo *p = NULL, *q = NULL;
   int i;
   int rc = 0;
   for (i = 0; i < 20; i++) {
   // add code for testing
       populatePerson(firstName, familyName, &id);
       insertToList(&empHead, id, firstName, familyName);
   }
  
   printList(empHead);
   printf("test SearchById ");
  
   q = p = searchById(empHead, 111);
   if (p == NULL) {
       printf("search by id failed ");
   } else {
       printNode(p);
   }
  
   CONTINUE;
   if (p != NULL) {
       for (i = 0; i < 4; i++) {
           populatePerson(firstName, familyName, &id);
           p = insertAfter(p, id, firstName, familyName);
       }
   }
   printList(empHead);

   // test delete after
   rc = deleteAfter(q, &id, firstName, familyName);
   printf("deleteAfter rc = %d ", rc);
   printList(empHead);
   CONTINUE;
   p = searchById(empHead, 111);
   if (p != NULL) {
       printf(" found name to delete ");
       printNode(p);
       strncpy(firstName, p->firstName, NAME_LENGTH);
       deleteNodeByName(&empHead, firstName, familyName, &id);
   }
   // bubbleSort(&empHead);
   printf(" sorted list ");
   printList(empHead);

   printf(" remove duplicates ");
   removeDuplicates(&empHead);
   printList(empHead);
   deleteList(&empHead);

   return 0;
}
/***************************************************************************/
/* purpose: the function populate the personal info
input/output
struct personalInfo *p - allocated memory to the struct pointer which the function assigns values.
*/
void populatePerson(char *firstName, char *familyName, int *id)
{
   static int initRand = 0;
   int j;
   char *first[5] = { "John", "Don", "Edna", "Bev", "Miya" };
   char *family[5] = { "Broker", "Smith", "Tower", "Little", "Bronson" };
   if (!initRand) {
       srand(1557);
       initRand ++;
   }
// populate the first name using a random i ndex to the first name array
   j = rand() % 5;
// copy the first name to the structure pointed by p using strcpy
   strncpy(firstName, first[j], NAME_LENGTH);
// populate the first name using a random i ndex to the first name array
   j = rand() % 5;
// copy the family name to the structure pointed by p using strcpy
   strncpy(familyName, family[j], NAME_LENGTH);
// populate the student id using the random numnber in the range of 0-4096
   *id = rand() % 150;
}

linked_list.c

/*
File name is linked_list.c
Purpose: file contains functions for manipulating singly linked list
*/
/******************************************************************/
// INCLUDE
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "linked_list.h"
/************************************************************************/
// Define
/************************************************************************/
/*
Purpose to create a new list element
id - id of person
firstName - first name of person
familyName - family name of person
return
A pointer to the node that was allocated.

*/
PersonalInfo* NewNode(unsigned int id, char *firstName, char *familyName){
   PersonalInfo* ret = malloc(sizeof(PersonalInfo));
   if(!ret) return NULL;
   ret->id = id;
   if(firstName)
       strcpy(ret->firstName, firstName);
   if(familyName)
       strcpy(ret->familyName, familyName);
   ret->next = NULL;
   return ret;
}
/*
Purpose: insert a new node into the list as the first element
input
id - id of person
firstName - first name of person
familyName - family name of person
input/output
head - head of linked list
return
A pointer to the node that was allocated.
NULL - if the operation was not successful
*/
PersonalInfo *insertToList(PersonalInfo **head, unsigned int id, char *firstName, char *familyName)
{
   PersonalInfo *ret = NewNode(id, firstName, familyName);
   ret->next = *head;   //it will handle NULL cases also
   *head = ret;
}
/************************************************************************/
/*
Purpose: insert a new node into the list after the given node
Input
node - the node after which the new node must be added to the list
id - id of person
firstName - first name of person
familyName - family name of person
return
A pointer to the node that was allocated.
NULL - if the operation was not successful
*/
PersonalInfo *insertAfter(PersonalInfo *node, unsigned int id, char *firstName, char *familyName)
{
// add code
   if(!node)
       return NULL;
   else{
       PersonalInfo *ret = NewNode(id, firstName, familyName);
       ret->next = node->next;
       node->next = ret;
       return ret;
   }

}
/************************************************************************/
/*
Purpose: create a new node and insert it into the end of the list
Input
head - the head of the list
id - id of person
firstName - first name of person
familyName - family name of person
return
A pointer to the node that was allocated.
NULL - if the operation was not successful
*/
PersonalInfo *insertLast(PersonalInfo **head, unsigned int id, char *firstName, char *familyName)
{
// add code
   PersonalInfo *ret = NewNode(id, firstName, familyName);
   if(!(*head)){
       *head = ret;
   } else {
       PersonalInfo *itr = *head;
       while(itr->next)
           itr = itr->next;
       itr->next = ret;
   }
   return ret;
}
/************************************************************************/
/*
Purpose: search for the first node with the matching firstName
Input
head - the head of the list
firstName - first name of person
return
a pointer to the node that was found.
NULL - if no node was found or list empty
*/
PersonalInfo *searchByName(PersonalInfo *head, char *firstName)
{
// add code
   PersonalInfo *itr = head;
   while(itr){
       if(strcmp(itr->firstName, firstName) == 0)
           return itr;
       itr = itr->next;
   }
   return NULL;
}
/************************************************************************/
/*
Purpose: search for the first node with the matching id
Input
head - the head of the list
id - id of person person
return
a pointer to the node that was allocated.
NULL - if no node was found or list empty
*/
PersonalInfo *searchById(PersonalInfo *head, unsigned int id)
{
// add code
   PersonalInfo *itr = head;
   while(itr){
       if(itr->id == id)
           return itr;
       itr = itr->next;
   }
   return NULL;
}
/***************************************************************/
/*
Purpose: delete the first node from the list
Input
head - the head of the list
output
head - the head of the list
firstName - first name of delted record
familyName - family name of deleted recrod
id - id of deleted record
return
0 if node was deleted
1 if node was not deleted or list is empty
*/
int deleteFromList(PersonalInfo **head, unsigned int *id,
                   char *firstName, char *familyName)
{
// add code
   PersonalInfo *itr = *head;
   if(!itr)
       return 1;

   *head = itr->next;
   if(id)
       *id = itr->id;
   if(firstName)
       strcpy(firstName, itr->firstName);
   if(familyName)
       strcpy(familyName, itr->familyName);

   free(itr);   //unallocate
   return 0;
}
/***************************************************************/
/*
Purpose: delete the last node from the list
Input
head - the head of the list
output
head - the head of the list
firstName - first name of delted record
familyName - family name of deleted recrod
id - id of deleted record
return
0 if node was deleted
1 if node was not deleted or list is empty
*/
int deleteLast(PersonalInfo **head, unsigned int *id,
               char *firstName, char *familyName)
{
// add code
   if(!(*head))
       return 1;
   else{
       PersonalInfo *itr = *head;
       if(!(itr->next)){
           //delete head
           *head = NULL;
           if(firstName)
               strcpy(firstName, itr->firstName);
           if(familyName)
               strcpy(familyName, itr->familyName);
           if(id)
               *id = itr->id;
           free(itr);
           return 0;
       }
       while(itr->next->next){
           itr = itr->next;
       }
       if(firstName)
           strcpy(firstName, itr->next->firstName);
       if(familyName)
           strcpy(familyName, itr->next->familyName);
       if(id)
           *id = itr->next->id;
       free(itr->next);
       itr->next = NULL;
   }
}
/************************************************************************/
/*
Purpose: delete the record after the given node
Input
node - a node in the list
output
firstName - first name of delted record
familyName - family name of deleted recrod
id - id of deleted record
return
0 if node was deleted
1 if node was not deleted (either input node is NULL or input node was the lastnode in the list)
*/
int deleteAfter(PersonalInfo *node, unsigned int *id,
                char *firstName, char *familyName)
{
// add code
   if(!node)
       return 1;
   PersonalInfo *itr = node->next;
   if(!itr)
       return 1;

   if(firstName)
       strcpy(firstName, itr->firstName);
   if(familyName)
       strcpy(familyName, itr->familyName);
   if(id)
       *id = itr->id;
   node->next = itr->next;
   free(itr);
   return 0;
}
/************************************************************************/
/*
Purpose: delete the first node with the matching firstName
Input
head - the head of the list
firstName - first name of person
output
head - the head of the list
firstName - first name of deleted record
familyName - family name of deleted recrod
id - id of deleted record
return
0 if node was deleted
1 if node was not found (e.g., list is empty, no such node exists)
*/
int deleteNodeByName(PersonalInfo **head, char *firstName,
                     char *familyName, unsigned int *id)
{
// add code
   PersonalInfo *itr = *head;
   if(!itr)    //NULL head
       return 1;

   else if(strcmp(itr->firstName, firstName) == 0){
       //head needs to be deleted
       *head = (*head)->next;

       if(firstName)
           strcpy(firstName, itr->firstName);
       if(familyName)
           strcpy(familyName, itr->familyName);
       if(id)
           *id = itr->id;
       free(itr);
       return 0;
   }

   while(itr->next){
       if(strcmp(itr->next->firstName, firstName) == 0){
           PersonalInfo *rm = itr->next;
           itr->next = itr->next->next;

           if(firstName)
               strcpy(firstName, itr->firstName);
           if(familyName)
               strcpy(familyName, itr->familyName);
           if(id)
               *id = itr->id;
           free(rm);
           return 0;
       }
       itr = itr->next;
   }
   return 1;
}
/************************************************************************/
/*
Purpose: deletes all nodes from the list
input/output
head - the head of the list
*/
void deleteList(PersonalInfo **head)
{
// add code
   PersonalInfo *itr = *head;
   PersonalInfo *rm;
   while(itr){
       rm = itr;
       itr = itr->next;
       free(rm);
   }
}
/************************************************************************/
/*
Purpose: prints the fields of a node
input:
node - a pointer to a given node
*/
void printNode(PersonalInfo *node)
{
   printf("%-20s %-20s %7d ", node->firstName, node->familyName, node->id);
}
/************************************************************************/
/*
Purpose: prints all the records in the list
input
head - the head of the list
*/
void printList(PersonalInfo *head)
{
// add code
   PersonalInfo *itr = head;
   while(itr){
       printNode(itr);
       itr = itr->next;
   }
}
/************************************************************************/
/*
Purpose: counts the number of nodes in the list
input
head - the head of the list
return
the number of nodes in the list
*/
int listSize(PersonalInfo *head)
{
// add code
   PersonalInfo *itr = head;
   int count = 0;
   while(itr){
       itr = itr->next;
       count++;
   }
   return count;
}
/************************************************************************/
/*
Purpose: counts the number of nodes in the list with a matching firstName
input
head - the head of the list
return
the number of nodes in the list that match the firstName
*/
int countRecords(PersonalInfo *head, char *firstName)
{
// add code
   PersonalInfo *itr = head;
   int count = 0;
   while(itr){
       itr = itr->next;
       if(strcmp(itr->firstName, firstName) == 0)
           count++;
   }
   return count;
}
/************************************************************************/
/*
Purpose: removes all duplicates records from the list. Duplicate records are determined by their first name.
You can assume that the listed is sorted by first name.
input
head - the head of the list
*/
void removeDuplicates(PersonalInfo **head)
{
// add code
   //if adjacent elements have same first name remove one of them
   PersonalInfo *itr = *head;
   while(itr->next){
       if(strcmp(itr->firstName, itr->next->firstName) == 0){
           itr = itr->next;
           deleteNodeByName(head, itr->firstName, NULL, NULL);
       }
       else
           itr = itr->next;
   }
}


linked_list.h

/*
File name is linked_list.h
Purpose: file contains functions for manipulating singly linked list
*/
#ifndef LINKED_LIST_2401_HEADER
#define LINKED_LIST_2401_HEADER 1
/************************************************************************/
// DEFINESD
#define NAME_LENGTH 16
/************************************************************************/
// STRUCTURES
typedef struct personalInfo {
   struct personalInfo *next;
   unsigned int id;
   char firstName[NAME_LENGTH];
   char familyName[NAME_LENGTH];
} PersonalInfo;
/************************************************************************/
// FUNCTION PROTOTYPES
// Insert Functions
PersonalInfo *insertToList(PersonalInfo **head, unsigned int id,
                           char *firstName, char *familyName);
PersonalInfo *insertAfter(PersonalInfo *node, unsigned int id,
                          char *firstName, char *familyName);
PersonalInfo *insertLast(PersonalInfo **head, unsigned int id,
                         char *firstName, char *familyName);
// Search Functions
PersonalInfo *searchByName(PersonalInfo *head, char *firstName);
PersonalInfo *searchById(PersonalInfo *head, unsigned int id);
// Delete Functions
int deleteFromList(PersonalInfo **head, unsigned int *id,
                   char *firstName, char *familyName);
int deleteLast(PersonalInfo **head, unsigned int *id,
               char *firstName, char *familyName);
int deleteAfter(PersonalInfo *node, unsigned int *id,
                char *firstName, char *familyName);
int deleteNodeByName(PersonalInfo **head, char *firstName,
                     char *lastName, unsigned int *id);
void deleteList(PersonalInfo **head);
// Print Functions
void printNode(PersonalInfo *node);
void printList(PersonalInfo *head);
// Counting Functions
int listSize(PersonalInfo *head);
int countRecords(PersonalInfo *head, char *firstName);
// Miscellaneous Functions
void removeDuplicates(PersonalInfo **head);
PersonalInfo* NewNode(unsigned int id, char *firstName, char *familyName);
#endif