From 0a6a739b6f2a9ad94cdaae4dedaef4dbd33c6852 Mon Sep 17 00:00:00 2001 From: MarcUs7i Date: Thu, 20 Mar 2025 15:42:49 +0100 Subject: [PATCH] completed everything --- simple_singly_linked_list.c | 255 +++++++++++++++++++++++++++--------- 1 file changed, 193 insertions(+), 62 deletions(-) diff --git a/simple_singly_linked_list.c b/simple_singly_linked_list.c index b869732..ca0e960 100644 --- a/simple_singly_linked_list.c +++ b/simple_singly_linked_list.c @@ -55,7 +55,7 @@ struct IntListData { /* abstract away and generalize also memory allocation for list nodes */ static IntListNode list_obtain_node(int data) { IntListNode node = (IntListNode)alloc_mem(sizeof(struct IntListNodeData)); - node->data = 0; + node->data = data; node->next = 0; return node; } @@ -84,7 +84,9 @@ void list_dump(char* prefix, IntList list) { */ IntList list_obtain() { IntList intList = (IntList)alloc_mem(sizeof(struct IntListData)); - intList->head = 0; + if (intList != 0) { + intList->head = 0; + } return intList; } @@ -100,7 +102,21 @@ IntList list_obtain() { * is set to 0, if the list was successfully released, otherwise it is left untouched. */ void list_release(IntList* p_list) { - free_mem(p_list); + if (p_list == 0 || *p_list == 0) { + return; + } + + IntList list = *p_list; + IntListNode current = list->head; + + while (current != 0) { + IntListNode next = current->next; + list_release_node(current); + current = next; + } + + free_mem(list); + *p_list = 0; } /** @@ -110,12 +126,7 @@ void list_release(IntList* p_list) { * @return `True` if the list is valid, false otherwise. */ bool list_is_valid(IntList list) { - if (list == 0) { - return false; - } - - // some checks - return true; + return list != 0; } /** @@ -125,16 +136,11 @@ bool list_is_valid(IntList list) { * @return `False` if the list contains one or more items, `true` otherwise. */ bool list_is_empty(IntList list) { - if (!list_is_valid) { + if (!list_is_valid(list)) { return true; } - if(list->head == 0) { - return true; - } - - // some checks - return false; + return list->head == 0; } /** @@ -144,17 +150,21 @@ bool list_is_empty(IntList list) { * @return The number of values the list contains. */ int list_get_size(IntList list) { - if(!list_is_valid) { - return -1; + if (!list_is_valid(list)) { + return 0; } - + + if (list_is_empty(list)) { + return 0; + } + int size = 0; IntListNode current = list->head; - while(current->next != 0) { + while (current != 0) { size++; current = current->next; } - + return size; } @@ -168,19 +178,18 @@ int list_get_size(IntList list) { * `false ` otherwise. */ bool list_contains(IntList list, int value) { - if(!list_is_valid || list_is_empty) { + if (!list_is_valid(list) || list_is_empty(list)) { return false; } - + IntListNode current = list->head; - while(current->next != 0) { - if(current->data == value) { + while (current != 0) { + if (current->data == value) { return true; } - current = current->next; } - + return false; } @@ -193,20 +202,20 @@ bool list_contains(IntList list, int value) { * is not available. */ int list_get_at(IntList list, unsigned int index) { - if(!list_is_valid || list_is_empty) { + if (!list_is_valid(list) || list_is_empty(list)) { return 0; } - - int i = 0; + + unsigned int i = 0; IntListNode current = list->head; - while(current->next != 0) { - if(i == index) { + while (current != 0) { + if (i == index) { return current->data; } - current = current->next; + i++; } - + return 0; } @@ -217,7 +226,23 @@ int list_get_at(IntList list, unsigned int index) { * @param value The value to append to the list. */ void list_insert(IntList list, int value) { - return; + if (!list_is_valid(list)) { + return; + } + + IntListNode newNode = list_obtain_node(value); + + if (list_is_empty(list)) { + list->head = newNode; + return; + } + + IntListNode current = list->head; + while (current->next != 0) { + current = current->next; + } + + current->next = newNode; } /** @@ -232,63 +257,169 @@ void list_insert(IntList list, int value) { * @param value The value to insert. */ void list_insert_at(IntList list, unsigned int index, int value) { - return; + if (!list_is_valid(list)) { + return; + } + + IntListNode newNode = list_obtain_node(value); + + if (list_is_empty(list)) { + list->head = newNode; + return; + } + + if (index == 0) { + newNode->next = list->head; + list->head = newNode; + return; + } + + unsigned int i = 0; + IntListNode current = list->head; + IntListNode previous = 0; + + while (current != 0 && i < index) { + previous = current; + current = current->next; + i++; + } + + previous->next = newNode; + newNode->next = current; } /** * Appends the `list_to_append` at the end of the given `list`. * The appended list is empty afterwards, because all nodes of that list * have been transferred to `list`. - * - * @param list The list that receives the other list. - * @param list_to_append The list that is appended to `list`. */ void list_append(IntList list, IntList list_to_append) { - return; + if (!list_is_valid(list) || !list_is_valid(list_to_append) || list_is_empty(list_to_append)) { + return; + } + + if (list_is_empty(list)) { + list->head = list_to_append->head; + } else { + IntListNode current = list->head; + while (current->next != 0) { + current = current->next; + } + + current->next = list_to_append->head; + } + + list_to_append->head = 0; } /** * Removes the first occurrance of `value` from the given list. - * If the list does not contain that value, the list shall not - * be modified. - * - * @param list The list from which the given value shall be removed. - * @param value The value to remove from the list. */ void list_remove(IntList list, int value) { - return; + if (!list_is_valid(list) || list_is_empty(list)) { + return; + } + + if (list->head->data == value) { + IntListNode old_head = list->head; + list->head = list->head->next; + list_release_node(old_head); + return; + } + + IntListNode current = list->head; + while (current->next != 0) { + if (current->next->data == value) { + IntListNode to_remove = current->next; + current->next = to_remove->next; + list_release_node(to_remove); + return; + } + current = current->next; + } } /** * Removes all occurrances of `value` from the list. - * If the list does not contain that value, the list shall not - * be modified. - * - * @param list The list from which all occurrances of `value` shall be removed. - * @param value The `value` to remove throughout the list. */ void list_remove_all(IntList list, int value) { - return; + if (!list_is_valid(list) || list_is_empty(list)) { + return; + } + + while (list->head != 0 && list->head->data == value) { + IntListNode old_head = list->head; + list->head = list->head->next; + list_release_node(old_head); + } + + if (list_is_empty(list)) { + return; + } + + IntListNode current = list->head; + while (current->next != 0) { + if (current->next->data == value) { + IntListNode to_remove = current->next; + current->next = to_remove->next; + list_release_node(to_remove); + } else { + current = current->next; + } + } } /** * Removes the value at the indexed position from the given list - * and provides that value. If the list does not have a value - * at that position, the list remains unmodified. - * - * @param list The list from which the value at the given index shall be returned. - * @param index The zero-based index of the value to return. - * @return The removed value or 0 in case of errors. + * and provides that value. */ int list_remove_at(IntList list, unsigned int index) { - return 0; + if (!list_is_valid(list) || list_is_empty(list)) { + return 0; + } + + if (index == 0) { + int value = list->head->data; + IntListNode old_head = list->head; + list->head = list->head->next; + list_release_node(old_head); + return value; + } + + unsigned int i = 0; + IntListNode current = list->head; + IntListNode previous = 0; + + while (current != 0 && i < index) { + previous = current; + current = current->next; + i++; + } + + if (current == 0) { + return 0; + } + + int value = current->data; + previous->next = current->next; + list_release_node(current); + return value; } /** * Clears the given list by removing all values from the list. - * - * @param list The list to clear. */ void list_clear(IntList list) { - return; + if (!list_is_valid(list) || list_is_empty(list)) { + return; + } + + IntListNode current = list->head; + while (current != 0) { + IntListNode next = current->next; + list_release_node(current); + current = next; + } + + list->head = 0; } \ No newline at end of file