From b9b0fe2a2b13342df976dba0cb1ee25235add969 Mon Sep 17 00:00:00 2001 From: mas Date: Wed, 30 Oct 2019 01:28:32 +0330 Subject: [PATCH 1/2] add link_list library there's an simple example in the simple.c use student struct for simple data element "create, delete and travel" through list On branch feature/link_list Changes to be committed: new file: a.out new file: link_list.c new file: link_list.h new file: simple.c Untracked files: ../linked-list.c ../linked-list.h --- DataStructures/link_list/a.out | Bin 0 -> 13840 bytes DataStructures/link_list/link_list.c | 365 +++++++++++++++++++++++++++ DataStructures/link_list/link_list.h | 218 ++++++++++++++++ DataStructures/link_list/simple.c | 108 ++++++++ 4 files changed, 691 insertions(+) create mode 100755 DataStructures/link_list/a.out create mode 100644 DataStructures/link_list/link_list.c create mode 100644 DataStructures/link_list/link_list.h create mode 100644 DataStructures/link_list/simple.c diff --git a/DataStructures/link_list/a.out b/DataStructures/link_list/a.out new file mode 100755 index 0000000000000000000000000000000000000000..2486fa5a25de5a453824640cff7d64ae8416416b GIT binary patch literal 13840 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 = 0; + list->head = NULL; + list->tail = NULL; + return (list); +} + +/** + * @brief Same as `list_create` except no dynamic + * allocation on the heap will be perform to create + * the list. + * @return a list_t value + */ +list_t list_create_static() +{ + return ((list_t) { + .size = 0, + .head = NULL, + .tail = NULL + }); +} + +/** + * @brief Clears the list by deleting every node in it. + * The list will still be usable after this call. + */ +void list_clear(list_t* list) +{ + node_t* node = list->head; + + while (!list_is_empty(list)) { + node_t* next = node->next; + + list_remove_node(list, node); + node = next; + } +} + +/** + * @brief Destroys every element of the given `list` and + * frees the memory allocated by the `list`. The given pointer + * will not be usable after a call to this function. + */ +void list_destroy(list_t* list) +{ + list_clear(list); + free(list); +} + +/** + * @brief Allows to iterate over each node held by the list by pushing + * each of them to the given `iterator`. + */ +void list_iterate_over_nodes(const list_t* list, list_predicate_t iterator, void* data) +{ + node_t* node = list->head; + + for (size_t i = 0; i < list->size; ++i) { + if (iterator(i, node, data) < 0) { + break; + } + node = node->next; + } +} + +/** + * @brief Searches the list for the given `node`. + * @return the found node if any, NULL otherwise. + */ +node_t* list_find_node(const list_t* list, const node_t* element) +{ + node_t* node = list->head; + + for (size_t i = 0; i < list->size; ++i) { + if (node == element) { + return (node); + } + node = node->next; + } + return (NULL); +} + +/** + * @brief Finds an element using the return value of the given `predicate`. + * @return the node matching the given predicate. + */ +node_t* list_find_node_if(const list_t* list, list_predicate_t iterator, void* data) +{ + node_t* node = list->head; + + for (size_t i = 0; i < list->size; ++i) { + if (iterator(i, node, data)) { + return (node); + } + node = node->next; + } + return (NULL); +} + +/** + * @return the size of the given `list`. That is, the number of nodes currently + * held by the list. + */ +size_t list_get_size(const list_t* list) +{ + return (list->size); +} + +/** + * @return a positive value if the given `list` is + * empty, zero otherwise. + */ +int list_is_empty(const list_t* list) +{ + return (list_get_size(list) == 0); +} + +/** + * @brief Creates a new node instance initialized + * with the given `element`. + * @return a new instance of a `node_t`. + */ +node_t* node_new(void* element) +{ + node_t* node; + + node = malloc(sizeof(*node)); + node->element = element; + node->next = NULL; + node->prev = NULL; + return (node); +} + +/** + * @brief Adds a new element to the `list`. This will cause a new `node_t` + * to be created, holding the given `element` and pushed at the front of the + * given `list`. + * @return a pointer to the newly created node. + */ +node_t* list_push_front(list_t* list, void* element) +{ + node_t* node = node_new(element); + node_t* head = list->head; + + if (head) { + // Binding the node to the list elements. + node->next = head; + node->prev = head->prev; + // Binding the list elements to the node. + head->prev->next = node; + head->prev = node; + } else { + node->next = node; + node->prev = node; + list->tail = node; + } + list->head = node; + list->size++; + return (node); +} + +/** + * @brief Adds a new element to the `list`. This will cause a new `node_t` + * to be created, holding the given `element` and pushed to the back of the + * given `list`. + * @return a pointer to the newly created node. + */ +node_t* list_push_back(list_t* list, void* element) +{ + node_t* node = node_new(element); + node_t* tail = list->tail; + + if (tail) { + // Binding the node to the list elements. + node->next = tail->next; + node->prev = tail; + // Binding the list elements to the node. + tail->next->prev = node; + tail->next = node; + } else { + node->next = node; + node->prev = node; + list->head = node; + } + list->tail = node; + list->size++; + return (node); +} + +/** + * @brief Removes the node associated with the given node pointer + * from the list. + * @return the pointer held by the removed node. + */ +void* list_pop_node(list_t* list, node_t* node) +{ + void* element; + + if (!node) { + return (NULL); + } + element = node->element; + list_remove_node(list, node); + return (element); +} + +/** + * @brief Removes the node located at the head of the list. + * @return the pointer held by the removed node. + */ +void* list_pop_back(list_t* list) +{ + return (list_pop_node(list, list->tail)); +} + +/** + * @brief Removes the node located at the tail of the list. + * @return the pointer held by the removed node. + */ +void* list_pop_front(list_t* list) +{ + return (list_pop_node(list, list->head)); +} + +/** + * @return a new instance of an iterator. The iterator's current node + * will be `node` if the given pointer is non-NULL, or the head of the + * given `list` otherwise. + */ +list_iterator_t list_make_iterator(list_t* list, node_t* node) +{ + return ((list_iterator_t) { + .current = (node != NULL ? node : list->head != NULL ? + list->head->prev : NULL), + .list = list + }); +} + +/** + * @return whether it is possible to go forward in the list. + */ +int list_iterator_has_next(const list_iterator_t* it) +{ + return (it->current != NULL && it->current->next != NULL); +} + +/** + * @return whether it is possible to go backward in the list. + */ +int list_iterator_has_prev(const list_iterator_t* it) +{ + return (it->current != NULL && it->current->prev != NULL); +} + +/** + * @brief Removes the current node from the list. + * @return a positive value if the removal succeeded, + * zero otherwise. + */ +int list_iterator_remove(list_iterator_t* it) +{ + node_t* current = it->current; + + if (!current) + return (0); + if (current == current->next) + it->current = NULL; + else + it->current = current->next; + return (list_remove_node(it->list, current)); +} + +/** + * @brief Moves the iterator's current node pointer forward. If + * it is not possible to do so, the function will not modify the + * iterator's current node pointer. + * @return the current node if moving forward succeeded, + * NULL otherwise. + */ +node_t* list_iterator_next(list_iterator_t* it) +{ + if (!list_iterator_has_next(it)) { + return (NULL); + } + return (it->current = it->current->next); +} + +/** + * @brief Moves the iterator's current node pointer backward. If + * it is not possible to do so, the function will not modify the + * iterator's current node pointer. + * @return the current node if moving backward succeeded, + * NULL otherwise. + */ +node_t* list_iterator_prev(list_iterator_t* it) +{ + if (!list_iterator_has_prev(it)) { + return (NULL); + } + return (it->current = it->current->prev); +} + +/** + * @brief Removes the given `node` from the `list` + * and frees the memory allocated by the `node`. + * @return a positive value if the given `node` has + * been successfully removed from the `list`, a negative + * value otherwise. + */ +int list_remove_node(list_t* list, node_t* node) +{ + node_t* found = list_find_node(list, node); + + if (found != NULL) { + found->prev->next = found->next; + found->next->prev = found->prev; + if (list->head == found) { + list->head = found->next; + } + if (list->tail == found) { + list->tail = found->prev; + } + list->size--; + if (list->size == 0) { + list->tail = NULL; + list->head = NULL; + } + free(found); + return (1); + } + return (0); +} + +/** + * @brief Conditionally removes a node from the list based on the return + * value of the given `predicate`. + * @return the number of removed nodes. + */ +int list_remove_node_if(list_t* list, list_predicate_t iterator, void* data) +{ + node_t* node = list->head; + int removed = 0; + + for (size_t i = 0; i < list->size; ++i) { + node_t* next = node->next; + + if (iterator(i, node, data)) { + list_remove_node(list, node); + removed++; + i -= 1; + } + node = next; + } + return (removed); +} diff --git a/DataStructures/link_list/link_list.h b/DataStructures/link_list/link_list.h new file mode 100644 index 0000000..d3b8e12 --- /dev/null +++ b/DataStructures/link_list/link_list.h @@ -0,0 +1,218 @@ +#ifndef CIRCULAR_LINKED_LIST +#define CIRCULAR_LINKED_LIST + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + /** + * @brief A node holds a pointer to the user-defined + * element required to be stored, a pointer to + * the next element in the list, and a pointer to + * the previous element in the list. + */ + typedef struct node_t + { + void* element; + struct node_t* next; + struct node_t* prev; + } node_t; + + /** + * @brief Definition of the circular doubly linked-list. + * It holds informations about the current size + * of the list, a pointer to the head node of the list, + * and a pointer to the tail of the list. + */ + typedef struct list_t + { + size_t size; + struct node_t* head; + struct node_t* tail; + } list_t; + + /** + * @brief The list iterator structure allows + * to memorize a pointer to a `node_t`. It also holds + * a pointer to the list the node belongs to. + * The `data` pointer is reserved for future usage. + * @see list_make_iterator + */ + typedef struct list_iterator_t + { + list_t* list; + node_t* current; + void* data; + } list_iterator_t; + + /** + * @brief A predicate type to be used when iterating over + * each node of the list. + * @see list_iterate_over_nodes + */ + typedef int (*list_predicate_t)(size_t index, node_t* node, void* data); + + /** + * @brief Creates a new instance of a `list_t`. + * @return a pointer to the created list. + */ + list_t* list_create(); + + /** + * @brief Same as `list_create` except no dynamic + * allocation on the heap will be perform to create + * the list. + * @return a list_t value + */ + list_t list_create_static(); + + /** + * @brief Clears the list by deleting every node in it. + * The list will still be usable after this call. + */ + void list_clear(list_t* list); + + /** + * @brief Destroys every element of the given `list` and + * frees the memory allocated by the `list`. The given pointer + * will not be usable after a call to this function. + */ + void list_destroy(list_t* list); + + /** + * @brief Adds a new element to the `list`. This will cause a new `node_t` + * to be created, holding the given `element` and pushed at the front of the + * given `list`. + * @return a pointer to the newly created node. + */ + node_t* list_push_front(list_t* list, void* element); + + /** + * @brief Adds a new element to the `list`. This will cause a new `node_t` + * to be created, holding the given `element` and pushed to the back of the + * given `list`. + * @return a pointer to the newly created node. + */ + node_t* list_push_back(list_t* list, void* element); + + /** + * @brief Allows to iterate over each node held by the list by pushing + * each of them to the given `iterator`. + */ + void list_iterate_over_nodes(const list_t* list, list_predicate_t iterator, void* data); + + /** + * @brief Searches the list for the given `node`. + * @return the found node if any, NULL otherwise. + */ + node_t* list_find_node(const list_t* list, const node_t* node); + + /** + * @brief Finds an element using the return value of the given `predicate`. + * @return the node matching the given predicate. + */ + node_t* list_find_node_if(const list_t* list, list_predicate_t iterator, void* data); + + /** + * @brief Removes the given `node` from the `list` + * and frees the memory allocated by the `node`. + * @return a positive value if the given `node` has + * been successfully removed from the `list`, a negative + * value otherwise. + */ + int list_remove_node(list_t* list, node_t* node); + + /** + * @brief Conditionally removes a node from the list based on the return + * value of the given `predicate`. + * @return the number of removed nodes. + */ + int list_remove_node_if(list_t* list, list_predicate_t predicate, void* data); + + /** + * @return the size of the given `list`. That is, the number of nodes currently + * held by the list. + */ + size_t list_get_size(const list_t* list); + + /** + * @return a positive value if the given `list` is + * empty, zero otherwise. + */ + int list_is_empty(const list_t* list); + + /** + * @brief Removes the node associated with the given node pointer + * from the list. + * @return the pointer held by the removed node. + */ + void* list_pop_node(list_t* list, node_t* node); + + /** + * @brief Removes the node located at the head of the list. + * @return the pointer held by the removed node. + */ + void* list_pop_back(list_t* list); + + /** + * @brief Removes the node located at the tail of the list. + * @return the pointer held by the removed node. + */ + void* list_pop_front(list_t* list); + + /** + * @return a new instance of an iterator. The iterator's current node + * will be `node` if the given pointer is non-NULL, or the head of the + * given `list` otherwise. + */ + list_iterator_t list_make_iterator(list_t* list, node_t* node); + + /** + * @return whether it is possible to go forward in the list. + */ + int list_iterator_has_next(const list_iterator_t* it); + + /** + * @return whether it is possible to go backward in the list. + */ + int list_iterator_has_prev(const list_iterator_t* it); + + /** + * @brief Moves the iterator's current node pointer forward. If + * it is not possible to do so, the function will not modify the + * iterator's current node pointer. + * @return the current node if moving forward succeeded, + * NULL otherwise. + */ + node_t* list_iterator_next(list_iterator_t* it); + + /** + * @brief Moves the iterator's current node pointer backward. If + * it is not possible to do so, the function will not modify the + * iterator's current node pointer. + * @return the current node if moving backward succeeded, + * NULL otherwise. + */ + node_t* list_iterator_prev(list_iterator_t* it); + + /** + * @brief Removes the current node from the list. + * @return a positive value if the removal succeeded, + * zero otherwise. + */ + int list_iterator_remove(list_iterator_t* it); + + /** + * @brief Creates a new node instance initialized + * with the given `element`. + * @return a new instance of a `node_t`. + */ + node_t* node_new(void* element); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/DataStructures/link_list/simple.c b/DataStructures/link_list/simple.c new file mode 100644 index 0000000..d92d7e7 --- /dev/null +++ b/DataStructures/link_list/simple.c @@ -0,0 +1,108 @@ +#include +#include +#include "link_list.h" + + +typedef enum Sex{ + male = 0, + female, + other +}Sex_TypeDef; + +typedef struct Student{ + + int no; + Sex_TypeDef sex; + +}Student_TypeDef; + + +void create_student(list_t *l){ + + int x; + + Student_TypeDef* s; + + s = malloc(sizeof(Student_TypeDef)); + + if (s == NULL){ + printf("\nbad malloc "); + return; + } + + printf("\nEnter student number: "); + scanf(" %d", &x); + s->no = x; + printf("\nEnter student sex(0:male 1:female 2:other): "); + scanf(" %d", &x); + s->sex = (Sex_TypeDef)x; + + list_push_front(l, s); +} + + +int find_student(size_t index, node_t *node, void* data){ + + Student_TypeDef *n = (Student_TypeDef *)node->element; + Student_TypeDef *d = (Student_TypeDef *)data; + + if(n->no == d->no) + return 1; + else + return 0; +} + +void delete_student(list_t *l){ + + int x; + Student_TypeDef* s; + + s = malloc(sizeof(Student_TypeDef)); + + if (s == NULL){ + printf("\nbad malloc "); + return; + } + + printf("\nEnter student number: "); + scanf(" %d", &x); + s->no = x; + + int a = list_remove_node_if(l, find_student, s); + printf("\n%d node deleted!", a); + +} + +int print_student(size_t index, node_t *node, void* data){ + + Student_TypeDef *s = (Student_TypeDef*)node->element; + printf("\nno: %d", (int)index); + printf("\n>>>Student Number: %d", s->no); + printf("\n>>>Enter student sex: %d ", s->sex); +} +void display_student(list_t *l){ + + void *data; + list_iterate_over_nodes(l, print_student, data); +} +void main() +{ + printf("< - Link List - Creation - Deletion - Traversal - >\n"); + int ch; + list_t *l; + l = list_create(); + while(1){ + printf("\n*********************************"); + printf("\n1. create/insert() \n2. display()\n3. delete()\n4.exit()\n Choice: "); + scanf(" %d", &ch); + + switch(ch){ + + case 1: create_student(l); break; + case 2: display_student(l); break; + case 3: delete_student(l); break; + case 4: exit(1); break; + default: printf("\nwrong input!");break; + } + } +} From f1222c2c6416ea1941d8c24a0ad28ed1ac4ad914 Mon Sep 17 00:00:00 2001 From: mas Date: Wed, 30 Oct 2019 01:35:18 +0330 Subject: [PATCH 2/2] remove a.out --- DataStructures/link_list/a.out | Bin 13840 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 DataStructures/link_list/a.out diff --git a/DataStructures/link_list/a.out b/DataStructures/link_list/a.out deleted file mode 100755 index 2486fa5a25de5a453824640cff7d64ae8416416b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13840 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