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);
|