Adding remove node method to generic list

This commit is contained in:
Michael Tryby
2019-04-24 16:29:57 -04:00
parent 9b3173f9be
commit d927851d20
3 changed files with 71 additions and 22 deletions

View File

@@ -132,16 +132,14 @@ void for_each_list(list_t *list, listIterator iterator)
list_node_t *head_list(list_t *list, bool removeFromList) list_node_t *head_list(list_t *list, bool removeFromList)
// Warning: When node is removed caller is responsible for freeing it. // Warning: When node is removed caller is responsible for freeing it.
{ {
// assert(list->head != NULL); if (list) {
list_node_t *node = list->head;
if (list) { if (removeFromList) {
list_node_t *node = list->head; // Disconnecting head node
if (removeFromList) { list->head = node->next;
// Disconnecting head node list->logicalLength--;
list->head = node->next; }
list->logicalLength--; return node;
}
return node;
} }
return NULL; return NULL;
} }
@@ -154,14 +152,14 @@ list_node_t *tail_list(list_t *list)
list_node_t *get_nth_list(list_t *list, int index) list_node_t *get_nth_list(list_t *list, int index)
{ {
int n; int n;
list_node_t *lnode; list_node_t *lnode;
for (n = 1, lnode = first_list(list); n < index && done_list(lnode); n++, lnode = next_list(lnode)); for (n = 1, lnode = first_list(list); n < index && done_list(lnode); n++, lnode = next_list(lnode));
if (n != index) if (n != index)
return NULL; return NULL;
else else
return lnode; return lnode;
} }
list_node_t *search_list(list_t *list, int key) list_node_t *search_list(list_t *list, int key)
@@ -170,15 +168,45 @@ list_node_t *search_list(list_t *list, int key)
list_node_t *lnode = first_list(list); list_node_t *lnode = first_list(list);
while (done_list(lnode)) { while (done_list(lnode)) {
if (get_key(lnode) == key) if (get_key(lnode) == key)
return lnode; return lnode;
lnode = next_list(lnode); lnode = next_list(lnode);
} }
return NULL; return NULL;
} }
void remove_node(list_t *list, int key)
{
list_node_t *temp;
list_node_t *target = search_list(list, key);
if (target == list->head)
delete_node(list, head_list(list, true));
else if (target == list->tail) {
// find next to last node
temp = list->head;
while (temp != NULL) {
if (temp->next == target)
break;
temp = temp->next;
}
// detatch tail
temp->next = NULL;
delete_node(list, list->tail);
}
else {
temp = target->next;
list->freeFn(target->data);
free(target->data);
target->data = temp->data;
target->next = temp->next;
free(temp);
}
}
int size_list(list_t *list) int size_list(list_t *list)
{ {
return list->logicalLength; return list->logicalLength;

View File

@@ -108,6 +108,11 @@ list_node_t *get_nth_list(list_t *list, int index);
*/ */
list_node_t *search_list(list_t *list, int key); list_node_t *search_list(list_t *list, int key);
/**
@brief Removes the list node with the given key from the list.
*/
void remove_node(list_t *list, int key);
// //
// Iterator first/done/next operations // Iterator first/done/next operations
// http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)Iterators.html // http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)Iterators.html

View File

@@ -195,14 +195,14 @@ char *get_name(list_node_t *lnode)
BOOST_AUTO_TEST_CASE(test_struct_list){ BOOST_AUTO_TEST_CASE(test_struct_list){
int key; int key, head_key, tail_key;
list_t *list = NULL; list_t *list = NULL;
list = create_list(sizeof(test_data_t *), delete_test_data); list = create_list(sizeof(test_data_t *), delete_test_data);
test_data_t *data = create_test_data(1, "David"); test_data_t *data = create_test_data(1, "David");
append_list(list, &data); head_key = append_list(list, &data);
data = create_test_data(2, "Kevin"); data = create_test_data(2, "Kevin");
key = append_list(list, &data); key = append_list(list, &data);
@@ -210,8 +210,13 @@ BOOST_AUTO_TEST_CASE(test_struct_list){
data = create_test_data(3, "Michael"); data = create_test_data(3, "Michael");
append_list(list, &data); append_list(list, &data);
data = create_test_data(4, "Craig");
append_list(list, &data);
BOOST_CHECK(size_list(list) == 3); data = create_test_data(5, "Jimi");
tail_key = append_list(list, &data);
BOOST_CHECK(size_list(list) == 5);
listIterator iterator = (listIterator)iterate_test_data; listIterator iterator = (listIterator)iterate_test_data;
for_each_list(list, iterator); for_each_list(list, iterator);
@@ -220,6 +225,17 @@ BOOST_AUTO_TEST_CASE(test_struct_list){
// locate a list node by a key // locate a list node by a key
printf("Found %s!\n", get_name(search_list(list, key))); printf("Found %s!\n", get_name(search_list(list, key)));
printf("Removing Kevin\n");
remove_node(list, key);
for_each_list(list, iterator);
printf("Removing David\n");
remove_node(list, head_key);
for_each_list(list, iterator);
printf("Removing Jimi\n");
remove_node(list, tail_key);
for_each_list(list, iterator);
list_node_t *lnode = head_list(list, true); list_node_t *lnode = head_list(list, true);
delete_node(list, lnode); delete_node(list, lnode);