forked from 131/lab6_list
87 lines
3.0 KiB
C
87 lines
3.0 KiB
C
#pragma once
|
||
|
||
#include <stdlib.h>
|
||
|
||
/* узел списка */
|
||
typedef struct list_node {
|
||
struct list_node *next; /* указатель на предыдущий элемент списка */
|
||
struct list_node *prev; /* указатель на следующий элемент списка */
|
||
} list_node;
|
||
|
||
/* структура, описывающая двусвязный список */
|
||
typedef struct {
|
||
list_node *head; /* указатель на голову списка */
|
||
list_node *tail; /* указатель на конец списка */
|
||
} list;
|
||
|
||
// Макро магия
|
||
#define list_for_each(iter, list) \
|
||
for (iter = list->head; iter != NULL; iter = iter->next)
|
||
|
||
typedef int (*list_pass_cb)(list_node *n, void *opaq);
|
||
typedef void (*list_free_cb)(list_node *n);
|
||
|
||
|
||
/* Инициализировать вектор (занулить указатели) */
|
||
void list_init(list *l);
|
||
|
||
/*
|
||
* Очистить список, удалив все элементы.
|
||
* *cb* -- опциональный параметр, с помощью которого передаётся функция, освобождающая объект
|
||
*/
|
||
void list_clear(list *l, list_free_cb cb);
|
||
|
||
list_node *list_first(list *l); /* Получить голову списка (или NULL, если список пустой) */
|
||
list_node *list_last(list *l); /* Получить конечный элемент списка (или NULL, если список пустой)*/
|
||
|
||
size_t list_len(list *l); /* Вернуть длину списка */
|
||
|
||
void list_push_front(list *l, list_node *node);
|
||
void list_push_back(list *l, list_node *node);
|
||
|
||
|
||
/*
|
||
* Get n'th element of list, return NULL if idx >= length(list)
|
||
*/
|
||
list_node *list_get(list *l, int idx);
|
||
|
||
/*
|
||
* Tries to insert node at idx position,
|
||
* calls xerror() (from util.h) if idx >= length(list)
|
||
* *Optional*: use negative idx to insert elements at the end of list
|
||
*/
|
||
void list_insert(list *l, list_node *node, int idx);
|
||
|
||
/*
|
||
* Удалить первый(последний) элемент списка.
|
||
* Если список пустой, ничего не делать и вернуть NULL
|
||
* NOTE: вы должны занулять указатели в list_node, который возвращаете
|
||
*/
|
||
list_node *list_pop_front(list *l);
|
||
list_node *list_pop_back(list *l);
|
||
|
||
/*
|
||
* Найти узел *n* в списке и вернуть
|
||
* порядковый номер узла в списке, или -1, если такого узла нет
|
||
*/
|
||
int list_index(list *l, list_node *n);
|
||
|
||
/*
|
||
* Удалить узел с порядковым номером idx
|
||
*/
|
||
list_node *list_remove(list *l, int idx);
|
||
|
||
/*
|
||
* Поменять порядок элементов в списке
|
||
* Т.е. Список [1, 2, 3, 4] должен стать [4, 3, 2, 1]
|
||
*/
|
||
void list_reverse(list *l);
|
||
|
||
void list_pass(list *l, list_pass_cb cb, void *opaq);
|
||
|
||
// Not implemented yet:
|
||
//
|
||
//typedef int (*list_cmp_cb)(list_node *a, list_node *b);
|
||
//void list_find(list *l, list_cmp_cb cb);
|
||
//void list_sort(list *l);
|