From 3f9d1c8cd03452aa2939e92690fc1b0f979750e2 Mon Sep 17 00:00:00 2001 From: m561247 Date: Fri, 23 Feb 2024 10:56:06 +0800 Subject: [PATCH] feat --- queue.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 133 insertions(+), 13 deletions(-) diff --git a/queue.c b/queue.c index 652ce1ccb..dcd92d358 100644 --- a/queue.c +++ b/queue.c @@ -1,7 +1,7 @@ #include #include #include - +#include #include "queue.h" /* Notice: sometimes, Cppcheck would find the potential NULL pointer bugs, @@ -14,7 +14,10 @@ /* Create an empty queue */ struct list_head *q_new() { - return NULL; + struct list_head *head = malloc(sizeof(struct list_head)); + assert(head != NULL && "Memory allocation failed"); + INIT_LIST_HEAD(head); + return head; } /* Free all storage used by queue */ @@ -23,60 +26,177 @@ void q_free(struct list_head *l) {} /* Insert an element at head of queue */ bool q_insert_head(struct list_head *head, char *s) { + assert(head != NULL && "Memory allocation failed"); + element_t *node = malloc(sizeof(element_t)); + assert(node != NULL && "Memory allocation failed"); + node->value = strdup(s); + assert(node->value == NULL && "node->value failed"); + node->list.next = head->next; + node->list.prev = head; + head->next->prev = &node->list; + head->next = &node->list; + return true; } /* Insert an element at tail of queue */ bool q_insert_tail(struct list_head *head, char *s) -{ +{ + assert(head != NULL && "Memory allocation failed"); + element_t *node = malloc(sizeof(element_t)); + assert(node != NULL && "Memory allocation failed"); + node->value = strdup(s); + node->list.next = head; + node->list.prev = head->prev; + head->prev->next = &node->list; + head->prev = &node->list; return true; } /* Remove an element from head of queue */ element_t *q_remove_head(struct list_head *head, char *sp, size_t bufsize) { - return NULL; + if (head == NULL || list_empty(head)) { + return NULL; + } + element_t *node = list_entry(head->next, element_t, list); + list_del(head->next); + if (sp != NULL) { + strncpy(sp, node->value, bufsize - 1); + sp[bufsize - 1] = '\0'; + } + return node; } /* Remove an element from tail of queue */ element_t *q_remove_tail(struct list_head *head, char *sp, size_t bufsize) { - return NULL; -} + if (head == NULL || list_empty(head)) { + return NULL; + } + element_t *node = list_entry(head->prev, element_t, list); + list_del(head->prev); + if (sp != NULL) { + strncpy(sp, node->value, bufsize - 1); + sp[bufsize - 1] = '\0'; + } + return node;} /* Return number of elements in queue */ int q_size(struct list_head *head) -{ - return -1; +{ + if (head == NULL || list_empty(head)) { + return 0; + } + int count = 0; + struct list_head *temp = head->next; + while (temp != head) + { + temp = temp->next; + count++; + } + + return count; } /* Delete the middle node in queue */ +// https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/ bool q_delete_mid(struct list_head *head) { - // https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/ + if (head == NULL || list_empty(head)) { + return false; + } + struct list_head *forward = head->next; + struct list_head *back = head->prev; + while (back != forward && back->prev != forward) { + forward = forward->next; + back = back->prev; + } + list_del(forward); + element_t *node = list_entry(forward, element_t, list); + q_release_element(node); return true; } /* Delete all nodes that have duplicate string */ +// https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ bool q_delete_dup(struct list_head *head) { - // https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ + if (head == NULL || list_empty(head)) { + return false; + } + bool dup = false; + element_t *temp, *next; + list_for_each_entry_safe(temp, next, head, list) { + if (temp->list.next != head && + strcmp(next->value, temp->value) == 0) { + list_del(&temp->list); + q_release_element(temp); + dup = true; + } else if (dup) { + list_del(&temp->list); + q_release_element(temp); + dup = false; + } + } return true; + } /* Swap every two adjacent nodes */ +// https://leetcode.com/problems/swap-nodes-in-pairs/ + void q_swap(struct list_head *head) { - // https://leetcode.com/problems/swap-nodes-in-pairs/ + if (head == NULL || list_empty(head)) { + return; + } + struct list_head *cur = head->next; + while (cur->next != head && cur != head) { + struct list_head *temp = cur->next; + list_move(cur, temp); + cur = cur->next; + } } /* Reverse elements in queue */ -void q_reverse(struct list_head *head) {} +void q_reverse(struct list_head *head) { + if (head == NULL || list_empty(head)) { + return ; + } + struct list_head *forward = head->next; + struct list_head *back = head->prev; + while (forward != back) { + struct list_head *temp = forward->next; + list_del(forward); + list_add(forward, back); + list_del(back); + list_add(back, temp); + if (back->next == forward) + break; + temp = back->next; + back = forward->prev; + forward = temp; + } +} /* Reverse the nodes of the list k at a time */ +// https://leetcode.com/problems/reverse-nodes-in-k-group/ + void q_reverseK(struct list_head *head, int k) { - // https://leetcode.com/problems/reverse-nodes-in-k-group/ + if (head == NULL || list_empty(head) || k < 2) { + return; + } + int list_size = q_size(head); + for (struct list_head *now = head->next; now != head && now->next != head; now = now->next) { + struct list_head **cur = &now->next, *temp = now->prev; + for (int i = 1; i < k; i++) { + if (list_size >= k) { + list_move(*cur, temp); + } + } + } } /* Sort elements of queue in ascending/descending order */