Программирование. Принципы и практика использования C++ Исправленное издание, стр. 399
void init(struct List* lst); /* инициализирует lst пустым */struct List* create(); /* создает новый пустой список в свободной памяти */void clear(struct List* lst); /* удаляет все элементы списка lst */void destroy(struct List* lst); /* удаляет все элементы списка lst, а затем удаляет сам lst */void push_back(struct List* lst, struct Link* p); /* добавляет элемент p в конец списка lst */void push_front(struct List*, struct Link* p); /* добавляет элемент p в начало списка lst *//* вставляет элемент q перед элементом p in lst: */void insert(struct List* lst, struct Link* p, struct Link* q);struct Link* erase(struct List* lst, struct Link* p); /* удаляет элемент p из списка lst *//* возвращает элемент, находящийся за n до или через n узлов после узла p:*/struct Link* advance(struct Link* p, int n);Мы хотим определить эти операции так, чтобы их пользователям было достаточно использовать только указатели
List*Link*ListLinkstruct List { struct Link* first; struct Link* last;};struct Link { /* узел двухсвязного списка */ struct Link* pre; struct Link* suc;};Приведем графическое представление контейнера
List
В наши намерения на входит демонстрация изощренных методов или алгоритмов, поэтому ни один из них на рисунке не показан. Тем не менее обратите внимание на то, что мы не упоминаем о данных, которые хранятся в узлах (элементах списков). Оглядываясь на функции-члены этой структуры, мы видим, что сделали нечто подобное, определяя пару абстрактных классов
LinkListLink*List*Link*List*ListLinkListДля реализации функций структуры
List#include<stdio.h>#include<stdlib.h>#include<assert.h>В языке C нет пространств имен, поэтому можно не беспокоиться о декларациях или директивах
usingLinkinsertinitИнициализация тривиальна, но обратите внимание на использование функции
assert()void init(struct List* lst) /* инициализируем *lst пустым списком */{ assert(lst); lst–>first = lst–>last = 0;}Мы решили не связываться с обработкой ошибок, связанных с некорректными указателями на списки, во время выполнения программы. Используя макрос
assert()assert()assert()<assert.h>Функция
create()Listinit()newmalloc()struct List* create() /* создает пустой список */{ struct List* lst = (struct List*)malloc(sizeof(struct List)); init(lst); return lst;}Функция
clear()free()void clear(struct List* lst) /* удаляет все элементы списка lst */