From 764847f7e498d94ae101d676c3ebc0fbc02dfe9c Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 2 Jul 2024 17:27:47 +0800 Subject: [PATCH] Finish some feature:) --- queue.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/queue.c b/queue.c index ce85f7d16..f02087509 100644 --- a/queue.c +++ b/queue.c @@ -14,34 +14,108 @@ /* Create an empty queue */ struct list_head *q_new() { - return NULL; + struct list_head *q = malloc(sizeof(struct list_head)); + if (!q) + return NULL; + INIT_LIST_HEAD(q); + return q; } /* Free all storage used by queue */ -void q_free(struct list_head *head) {} +void q_free(struct list_head *head) +{ + if (!head) + return; + struct list_head *cur = head->next; + while (cur != head) { + element_t *e = list_entry(cur, element_t, list); + cur = cur->next; + free(e->value); + free(e); + } + free(head); +} /* Insert an element at head of queue */ bool q_insert_head(struct list_head *head, char *s) { + // Be care of strlen vs sizeof + if (!head) + return false; + + element_t *temp = malloc(sizeof(element_t)); + if (!temp) + return false; + + size_t len = strlen(s) + 1; + temp->value = malloc(len * sizeof(char)); + if (!(temp->value)) { + free(temp); + return false; + } + memcpy(temp->value, s, len); + *(temp->value + len - 1) = '\0'; + list_add(&temp->list, head); return true; } /* Insert an element at tail of queue */ bool q_insert_tail(struct list_head *head, char *s) { + if (!head) + return false; + element_t *temp = malloc(sizeof(element_t)); + if (!temp) + return false; + + size_t len = strlen(s) + 1; + temp->value = malloc(len * sizeof(char)); + if (!(temp->value)) { + free(temp); + return false; + } + memcpy(temp->value, s, len); + *(temp->value + len - 1) = '\0'; + list_add_tail(&temp->list, head); 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 || list_empty(head)) + return NULL; + /*Get the element_t*/ + element_t *e = list_entry(head->next, element_t, list); + if (sp) { + size_t len = + (bufsize - 1) > strlen(e->value) ? strlen(e->value) : (bufsize - 1); + /*memcpy element value to sp and assign a NULL terminator to the end of + * the MEM. space*/ + memcpy(sp, e->value, len); + *(sp + len) = '\0'; + } + list_del_init(head->next); + return e; } /* 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 || list_empty(head)) + return NULL; + /*Get the element_t*/ + element_t *e = list_entry(head->prev, element_t, list); + if (sp) { + size_t len = + (bufsize - 1) > strlen(e->value) ? strlen(e->value) : (bufsize - 1); + /*memcpy element value to sp and assign a NULL terminator to the end of + * the MEM. space*/ + memcpy(sp, e->value, len); + *(sp + len) = '\0'; + } + list_del_init(head->prev); + return e; } /* Return number of elements in queue */ @@ -54,6 +128,22 @@ int q_size(struct list_head *head) bool q_delete_mid(struct list_head *head) { // https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/ + if (!head || list_empty(head)) + return false; + + struct list_head *fast = head; + struct list_head *slow = head; + + while (fast != head && fast->next != head) { + slow = slow->next; + fast = fast->next->next; + } + + element_t *e = list_entry(slow, element_t, list); + list_del_init(&e->list); + free(e->value); + free(e); + return true; }