Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 9 лет назад пользователемДарья Мачихина
1 Сложные структуры данных Связные списки
2 Структуры, ссылающиеся на себя struct node { int x; struct node *next; };
3 Связный список Структура данных, представляющая собой конечное множество упорядоченных элементов (узлов), связанных друг с другом посредством указателей, называется связным списком. Каждый элемент связного списка содержит поле с данными, а также указатель (ссылку) на следующий и/или предыдущий элемент. Эта структура позволяет эффективно выполнять операции добавления и удаления элементов для любой позиции в последовательности.
4 Недостатки связного списка Недостатком связного списка, как и других структур типа «список», в сравнении его с массивом, является отсутствие возможности работать с данными в режиме произвольного доступа, т. е. список – структура последовательно доступа, в то время как массив – произвольного.
5 Односвязный список Каждый узел односвязного (однонаправленного связного) списка содержит указатель на следующий узел. Из одной точки можно попасть лишь в следующую точку, двигаясь тем самым в конец. Так получается своеобразный поток, текущий в одном направлении.
6 Односвязный список Каждый из блоков представляет элемент (узел) списка. Здесь и далее Head list – заголовочный элемент списка (для него предполагается поле next). Он не содержит данные, а только ссылку на следующий элемент. На наличие данных указывает поле info, а ссылки – поле next. Признаком отсутствия указателя является поле nil.
7 Односвязные и двусвязные списки Односвязный список не самый удобный тип связного списка, т. к. из одной точки можно попасть лишь в следующую точку, двигаясь тем самым в конец. Когда кроме указателя на следующий элемент есть указатель на предыдущий, то такой список называется двусвязным.
8 Двусвязный список Особенность двусвязного списка, что каждый элемент имеет две ссылки: на следующий и на предыдущий элемент, позволяет двигаться как в его конец, так и в начало. Операции добавления и удаления здесь наиболее эффективны, чем в односвязном списке, поскольку всегда известны адреса тех элементов списка, указатели которых направлены на изменяемый элемент. Но добавление и удаление элемента в двусвязном списке, требует изменения большого количества ссылок, чем этого потребовал бы односвязный список.
9 Двусвязный список Возможность двигаться как вперед, так и назад полезна для выполнения некоторых операций, но дополнительные указатели требуют задействования большего количества памяти, чем таковой необходимо в односвязном списке.
10 Кольцевой список Еще один вид связного списка – кольцевой список. В кольцевом односвязном списке последний элемент ссылается на первый. В случае двусвязного кольцевого списка – плюс к этому первый ссылается на последний. Таким образом, получается зацикленная структура.
11 Управление памятью Для создания и использования динамических структур требуется динамическое распределение памяти возможность получения памяти для хранения новых узлов и освобождать память для удаления узлов.
12 Управление памятью Функции для управления динамической памятью объявлены в stdlib.h функция для выделения памяти: void* malloc (size_t size); Функция для освобождения ранее выделенной памяти: void free (void* ptr);
13 malloc void* malloc (size_t size); Резервирует блоки памяти размером size байт памяти и возвращает указатель на начало зарезервированного участка памяти. Например: newPtr = malloc (sizeof( struct node )); sizeof( struct node ) определяет размер в байтах структуры типа struct node, а malloc выделяет новый блок памяти размером в sizeof( struct node ) и возвращает указатель на выделенную память в newPtr. Если памяти для выделения не достаточно, то malloc возвращает указатель на NULL
14 free void free (void* ptr); Освобождает память, т.е. память возвращается системе, и в дальнейшем её можно будет выделить снова. Например: free (newPtr); После того как выделенная память больше не нужна необходимо её освободить при помощи free. Так же это не обходимо делать перед завершением программы, если память ещё не была освобождена.
15 #include struct node { int x; struct node *next; }; int main() { /* Обычная структура */ struct node *root; /* Теперь root указывает на структуру node */ root = (struct node *) malloc( sizeof(struct node) ); /* Узел root указывает на следующий элемент, которого пока нет */ root->next = NULL; /* Использование оператора -> позволяет изменять узел структуры, на которую он указывает */ root->x = 5; free ( root ); return 0; }
16 int main() { /* Это менять нельзя, т.к. тогда мы потеряем список в памяти */ struct node *root; /* Это указывает на каждый элемент списка, пока мы пробегаем по нему */ struct node *conductor; root = malloc( sizeof(struct node) ); root->next = 0; root->x = 12; conductor = root; if ( conductor != 0 ) { while ( conductor->next != 0) { conductor = conductor->next; }
next = 0; conductor->x = 42; ret" title="/* Создаёт новый узел в конце */ conductor->next = malloc( sizeof(struct node) ); conductor = conductor->next; if ( conductor == 0 ) { printf("Не хватает памяти!\n"); return 0; } /* инициализируем память */ conductor->next = 0; conductor->x = 42; ret" class="link_thumb"> 17 /* Создаёт новый узел в конце */ conductor->next = malloc( sizeof(struct node) ); conductor = conductor->next; if ( conductor == 0 ) { printf("Не хватает памяти!\n"); return 0; } /* инициализируем память */ conductor->next = 0; conductor->x = 42; return 0; } next = 0; conductor->x = 42; ret"> next = 0; conductor->x = 42; return 0; }"> next = 0; conductor->x = 42; ret" title="/* Создаёт новый узел в конце */ conductor->next = malloc( sizeof(struct node) ); conductor = conductor->next; if ( conductor == 0 ) { printf("Не хватает памяти!\n"); return 0; } /* инициализируем память */ conductor->next = 0; conductor->x = 42; ret">
18 conductor = root; if ( conductor != 0 ) { /* убедимся, что существует место старта*/ while ( conductor->next != 0 ) { printf( "%d\n", conductor->x); conductor = conductor->next; } printf( "%d\n", conductor->x ); } x); conductor = conductor->next; } printf( "%d\n", conductor->x ); }">
19 conductor = root; while ( conductor != NULL ) { printf( "%d\n", conductor->x ); conductor = conductor->next; } x ); conductor = conductor->next; }">
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.