|
|||||
Cтруктуры данных. Хранение информации.Рекурсивные структуры данных: общие сведения.© Кантор И. Основа всех подобных структур - список. Объявим его элемент следующим образом:
typedef struct list_ {
int data; // Место для данных, естественно, не всегда int.
struct list_ *next; // Указатель на такой же элемент (или на NULL)
} list;
Cоздадим такой элемент и проинициализуем его:list *OurList; OurList = (list *)malloc(sizeof(list)); Ourlist->data = 123; // Данные, естественно, могут быть любые Ourlist->next = NULL; // На NULL всегда указывает только последний в списке
Теперь мы можем добавить еще один элемент за ним: OurList -> next = (list *)malloc(sizeof(list)); И, при необходимости, переместить его вперед: OurList -> next -> next = OurList; // 'разворачиваем' новый элемент OurList -> next = NULL; // А теперь - старый Такие операции могут иметь свои нюансы, но, поняв устройство структуры, вы легко составите нужный алгоритм. Обычно что-то странное может быть с первым и последним элементом нашего 'паровозного состава'. Один элемент в списке всегда указывает на NULL - чтобы циклу, перебирающему элементы списка, или другой программе было видно, где конец списка (ведущий элемент 'поезда'). ![]() Предполагая, что X и P являются указателями, число 18 можно вставить в такой список следующим образом: X->Next = P->Next; P->Next = X; ![]() Вначалe вы можете создать указатель last_vagon, указывающий на начальный элемент списка (последний в 'поезде'), и далее 'продвигаться по вагонам' при создании новых элементов или поиске нужных. Создание и инициализация списка.
last_vagon = OurList;
while ( Требуется создать элемент списка )
{
// Переходим к следующему вагону.
OurList = Ourlist -> next;
// инициализация элемента
OurList = (list *)malloc(sizeof(list));
Заполнить данными ( OurList );
}
// Конец указывает на NULL
OurList -> next = NULL;
...
Начало не потеряно - есть указатель last_vagon ! От него мы можем добраться до любого элемента списка. Таким образом мы можем сохранять указатели на любые фиксированные элементы. Обычно их нужно 1-2 штуки кроме основного. Очевидно, возможна реализация, когда каждый новый элемент добавляется с другого конца списка - в этом случае // Прибавление к списку с левого конца элемента NewElem temp = OurList; NewElem -> next = OurList; // OurList будет всегда указывать на конец состава. OurList = new; ... Пример функции, последовательно обрабатывающей все элементы, следующие за OurList.
last_vagon = OurList;
while ( OurList -> next != NULL )
{
// Переходим к следующему вагону.
OurList = Ourlist -> next;
Обработать (OurList);
}
// OurList теперь указывает на правый конец списка.
// Начало не потеряно: есть указатель last_vagon !
// От него мы cможем добраться до любого элемента списка.
...
Списки бывают односвязные - как описано и двусвязные - с указателями в обе стороны. Мы можем создавать свои функции для работы со списками и менять сами списки для обеспечения максимального удобства. Перечислю стандартные реализации (которые, естественно, могут быть выполнены и на массивах):
Чем хороши/плохи структуры, основанные на списках ?В первую очередь по сравнению с массивом:Плюсы:
Вверх по странице, к оглавлению и навигации. | |||||