From 3c9bd4a703a3d09359b2778c171cf664e6b7ab8d Mon Sep 17 00:00:00 2001 From: alexey Date: Thu, 11 Dec 2025 11:32:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=85=D0=BE=D0=B4=D1=8F=D1=82=20=D0=B2=D1=81?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- list.c | 213 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 158 insertions(+), 55 deletions(-) diff --git a/list.c b/list.c index 11309fd..3c80b88 100644 --- a/list.c +++ b/list.c @@ -1,136 +1,239 @@ - #include #include #include "util.h" #include "list.h" - void list_init(list *l) { - assert(l); - memset(l, 0, sizeof(*l)); + assert(l); + memset(l, 0, sizeof(*l)); } static inline list_node * list_node_orphan(list_node *li) { - li->next = NULL; - li->prev = NULL; - return li; + li->next = NULL; + li->prev = NULL; + return li; } //NOTE: Можем ли мы расчитывать на то, что node->next валидно после вызова list_free_cb??? void list_clear(list *l, list_free_cb cb) { - assert(l); - // + assert(l); + + list_node *cur = l->head; + while (cur) { + list_node *next_node = cur->next; + + if (cb) + cb(cur); + + cur = next_node; + } + + l->head = NULL; + l->tail = NULL; } void list_push_front(list *l, list_node *item) { - assert(l && item); - // + assert(l && item); + + item->prev = NULL; + item->next = l->head; + + if (l->head) + l->head->prev = item; + else + l->tail = item; + + l->head = item; } void list_push_back(list *l, list_node *item) { - assert(l && item); - // + assert(l && item); + + item->next = NULL; + item->prev = l->tail; + + if (l->tail) + l->tail->next = item; + else + l->head = item; + + l->tail = item; } list_node * list_first(list *l) { - assert(l); - return l->head; + assert(l); + return l->head; } list_node * list_last(list *l) { - assert(l); - return l->tail; + assert(l); + return l->tail; } size_t list_len(list *l) { - assert(l); - // - return 0; + assert(l); + + size_t cnt = 0; + for (list_node *cur = l->head; cur; cur = cur->next) + cnt++; + + return cnt; } list_node * list_get(list *l, int idx) { - assert(l); - // - return NULL; + assert(l); + + if (idx < 0) + return NULL; + + int i = 0; + for (list_node *cur = l->head; cur; cur = cur->next, i++) + if (i == idx) + return cur; + + return NULL; } void list_insert(list *l, list_node *item, int idx) { - assert(l && item); - // + assert(l && item); + + int len = (int)list_len(l); + + if (idx < 0 || idx > len) + xerror(1, "index out of range\n"); + + if (idx == 0) { + list_push_front(l, item); + return; + } + + if (idx == len) { + list_push_back(l, item); + return; + } + + list_node *pos = list_get(l, idx); + assert(pos); + + item->prev = pos->prev; + item->next = pos; + + pos->prev->next = item; + pos->prev = item; } list_node * list_pop_front(list *l) { - assert(l); - // - return NULL; + assert(l); + + if (!l->head) + return NULL; + + list_node *res = l->head; + + l->head = res->next; + + if (l->head) + l->head->prev = NULL; + else + l->tail = NULL; + + return list_node_orphan(res); } list_node * list_pop_back(list *l) { - assert(l); - // - return NULL; + assert(l); + + if (!l->tail) + return NULL; + + list_node *res = l->tail; + + l->tail = res->prev; + + if (l->tail) + l->tail->next = NULL; + else + l->head = NULL; + + return list_node_orphan(res); } int list_index(list *l, list_node *n) { - assert(l && n); - list_node *tmp; - int i = 0; - for (tmp = l->head; tmp != NULL; tmp = tmp->next) { - if (tmp == n) - return i; - i++; - } - return -1; + assert(l && n); + + int i = 0; + for (list_node *cur = l->head; cur; cur = cur->next, i++) + if (cur == n) + return i; + + return -1; } list_node * list_remove(list *l, int idx) { - assert(l); - // - return NULL; + assert(l); + + list_node *cur = list_get(l, idx); + if (!cur) + return NULL; + + if (cur->prev) + cur->prev->next = cur->next; + else + l->head = cur->next; + + if (cur->next) + cur->next->prev = cur->prev; + else + l->tail = cur->prev; + + return list_node_orphan(cur); } void list_reverse(list *l) { - assert(l); - // + assert(l); + + list_node *cur = l->head; + list_node *tmp = NULL; + + while (cur) { + tmp = cur->next; + cur->next = cur->prev; + cur->prev = tmp; + cur = tmp; + } + + tmp = l->head; + l->head = l->tail; + l->tail = tmp; } - - -void -list_pass(list *l, list_pass_cb cb, void *opaq) -{ - struct list_node *iter; - list_for_each(iter, l) { - cb(iter, opaq); - } -} \ No newline at end of file