#include #include #include /* struct employee definition */ struct employee { char first[56]; char last[56]; char ssn[12]; int age; double salary; struct employee* next; }; /* prototypes */ void process(struct employee* l); struct employee* make_employee(char first[], char last[], char ssn[], int age, double salary, struct employee* next); struct employee* add_employee(struct employee* l, char insert_before[], char first[], char last[], char ssn[], int age, double salary); void print(struct employee* l); struct employee* delete_employee(struct employee* l, char first[], char last[]); struct employee* delete_last(struct employee* l); struct employee* delete_last_n(struct employee* l, int n); void destroy(struct employee* l); int main() { /* accept commands from the user, list is initially NULL */ process(NULL); return 0; } /* process user's commands */ void process(struct employee* l) { char first[56]; char last[56]; char ssn[12]; int age; double salary; char insert_ssn[12]; int n; int choice; printf("1. add employee\n2. delete employee\n"); printf("3. delete last n employees\n4. print employees\n5. quit\n"); scanf("%d", &choice); if(choice == 1) { printf("enter first, last, ssn, age, salary, ssn to insert before:\n"); scanf("%s %s %s %d %lf %s", first, last, ssn, &age, &salary, insert_ssn); l = add_employee(l, insert_ssn, first, last, ssn, age, salary); } else if(choice == 2) { printf("enter first, last:\n"); scanf("%s %s", first, last); l = delete_employee(l, first, last); } else if(choice == 3) { printf("enter n:\n"); scanf("%d", &n); l = delete_last_n(l, n); } else if(choice == 4) print(l); else if(choice == 5) { destroy(l); return; } process(l); } /* make new employee - allocate memory, initialize it, and return a * pointer to the new employee */ struct employee* make_employee(char first[], char last[], char ssn[], int age, double salary, struct employee* next) { /* make new list node */ struct employee* newguy = (struct employee*) malloc(sizeof(struct employee)); /* fill in list node */ strcpy(newguy->first, first); strcpy(newguy->last, last); strcpy(newguy->ssn, ssn); newguy->age = age; newguy->salary = salary; newguy->next = next; return newguy; } /* add employee to list - if the ssn to insert before does not exist, * the new employee is added to the end of the list */ struct employee* add_employee(struct employee* l, char insert_ssn[], char first[], char last[], char ssn[], int age, double salary) { struct employee* tmp; /* base case: if list is empty, return new list node */ if(l == NULL) return make_employee(first, last, ssn, age, salary, NULL); /* base case: if we find the guy to insert before, set new node's * next to point to rest of list, and return new list node */ else if(0 == strcmp(l->ssn, insert_ssn)) return make_employee(first, last, ssn, age, salary, l); /* recursive case: insert into remainder of list, set our next * pointer to be whatever the recursive call returns, and return a * pointer to this list node */ else { l->next = add_employee(l->next, insert_ssn, first, last, ssn, age, salary); return l; } } /* print list */ void print(struct employee* l) { /* base case: if list is empty, we're done */ if(l == NULL) return; /* recursive case: print contents of this node, then print the rest * of the list */ else { printf("first: %s\nlast: %s\nssn: %s\nage: %d\nsalary: %lf\n\n", l->first, l->last, l->ssn, l->age, l->salary); print(l->next); } } /* delete employee - if the list does not contain the employee to be * deleted, the list is not modified */ struct employee* delete_employee(struct employee* l, char first[], char last[]) { /* base case: if list is empty, we're done */ if(l == NULL) return l; /* base case: if we find the guy we're trying to delete, return * the next node in the list */ else if(0 == strcmp(l->first, first) && 0 == strcmp(l->last, last)) return l->next; /* recursive case: if we haven't found the the person to delete, * check the rest of the list, and set our next pointer to whatever * the recursive call returns. finally, return a pointer to the * current list node */ else { l->next = delete_employee(l->next, first, last); return l; } } /* delete last employee */ struct employee* delete_last(struct employee* l) { /* base case: if list is empty, we're done */ if(l == NULL) return l; /* base case: if we're the last node, kill ourselves */ else if(l->next == NULL) { free(l); return NULL; } /* recursive case: keep looking for the last node, and set next * pointers appropriately */ else { l->next = delete_last(l->next); return l; } } /* delete last n employees */ struct employee* delete_last_n(struct employee* l, int n) { /* base case: if we want to delete 0 things or less, we're done */ if(n <= 0) return l; /* base case: if our list doesn't have any more things, we're done */ else if(l == NULL) return l; /* recursive case: delete one thing, and then delete n-1 more */ else return delete_last_n(delete_last(l), n-1); } /* destroy list - free everything */ void destroy(struct employee* l) { struct employee* tmp; /* base case: if list is empty, we're done */ if(l == NULL) return; /* recursive case: destroy current node, then destroy rest of list */ else { tmp = l->next; free(l); destroy(tmp); } }