Динамические типы данных. Списки

Содержание

Слайд 2

1. Назначение и виды списков Списком называется упорядоченное, возможно пустое, множество

1. Назначение и виды списков

Списком называется упорядоченное, возможно пустое, множество (набор) элементов

(узлов), которые состоят из данных и полей связи между узлами.
К спискам применимы ряд операций, например, включения, исключения, копирования, поиска, сортировки.

Списки – наиболее широко применяемая в программировании динамическая структура данных:
- при решении прикладных задач программирования:
при организации списков объектов (пользователей, задач, документов, рассылки, и т.п.);
- в системном императивном программировании:
при реализации ядра ОС;
при реализации СУБД;
при реализации пользовательского интерфейса;
при работе с файлами;
при построении других динамических структур данных: стеки, очереди, деревья, сети и графы, хеш-таблицы;
при построении трансляторов;
в функциональном программировании:
язык ЛИСП и его диалекты

Слайд 3

Виды связных списков Связные списки Нелинейные Односвязные Двусвязные Циклические Линейные Мультисписки

Виды связных списков

Связные списки

Нелинейные

Односвязные

Двусвязные

Циклические

Линейные

Мультисписки

Линейные – все узлы расположены на одном уровне

(в линию).
Мультисписки – узлы могут быть элементами нескольких списков.
Нелинейные – узлы расположены на разных уровнях.
Вложенные – узлами могут быть другие списки (подсписки).

Вложенные

Слайд 4

Особенности списков Последовательный доступ (вместо прямого, как у массивов). Произвольное размещение

Особенности списков

Последовательный доступ (вместо прямого, как у массивов).
Произвольное размещение в динамической

памяти.
Используются указатели для реализации полей связи.

Достоинства:
лёгкость добавления и удаления элементов;
размер ограничен только объёмом памяти компьютера и разрядностью указателей;

Недостатки:
на поля связи (указатели на следующий и предыдущий элемент) расходуется дополнительная пам’ять;
работа со списком медленнее, чем с массивами, так как к любому элементу списка можно обратиться, только пройдя все предшествующие ему элементы;
элементы списка могут быть расположены в памяти разреженно, что окажет негативный эффект на кэширование процессора;

Слайд 5

2. Линейные односвязные списки Односвязный список состоит из узлов (элементов), которые

2. Линейные односвязные списки

Односвязный список состоит из узлов (элементов), которые состоят

из поля данных и указателя на следующий узел.
Начальный узел называется головой списка.
Значение указателя связи последнего узла равно NULL.
Полей данных может быть несколько.

Сравнение массивов и списков

Слайд 6

Операции над списками создание списка; печать (просмотр) списка; вставка элемента в

Операции над списками
создание списка;
печать (просмотр) списка;
вставка элемента в список;
удаление элемента из

списка;
поиск элемента в списке
удаление списка.
Слайд 7

Описание узла списка struct Node { int data; // поле данных

Описание узла списка

struct Node
{
int data; // поле данных
Node *next; // указатель

на след.узел
};

typedef Node *PNode; // тип данных: указатель на узел
PNode PHead; // указатель на голову списка
PHead = NULL; // список пуст

Создание списка

PNode createNode (int num)
{
PNode PNew = new Node; // указатель на новый узел
PNew->data = num; // поле данных – номер узла
PNew->next = NULL; // следующего узла нет
return PNew; // результат функции – адрес узла
}

Создание узла

Слайд 8

Добавление узла в список PNew = CreateNode (1); PHead = PNew;

Добавление узла в список

PNew = CreateNode (1);
PHead = PNew;

в пустой список:

void

addFirst (PNode &PHead, PNode PNew)
{
// установить next нового узла на голову списка
PNew->next = PHead;
//установить голову списка на новый узел
PHead = PNew;
}

в начало списка:

адрес головы списка передается по ссылке

1

2

Слайд 9

Добавление узла в список После заданного узла: data NULL data next

Добавление узла в список

После заданного узла:

data

NULL

data

next

data

NULL

data

NULL

data

next

data

NULL

void addAfter (PNode p, PNode PNew)
{
//установить

next нового узла на узел, следующий за заданным PNew->next = p->next;// p – указатель на заданный узел
//установить next заданного узла на новый узел
p->next = PNew;
}

Последовательность операций менять нельзя, т.к. будет потерян адрес узла, следующего за заданным.

1

p

Слайд 10

void addLast(PNode PHead, PNode PNew) { PNode q = PHead; if

void addLast(PNode PHead, PNode PNew)
{
PNode q = PHead;
if (Head == NULL)

{ // если список пуст,
AddFirst(Head, NewNode); // вставляем первый элемент
return;
}
while (q->next) q = q->next; // ищем последний элемент
AddAfter(q, PNew);
}

Добавление узла в конец списка

Слайд 11

void addBefore(PNode PHead, PNode p, PNode PNew) { PNode q =

void addBefore(PNode PHead, PNode p, PNode PNew)
{
PNode q = PHead;
if (Head

== p) {
AddFirst(Head, NewNode); // вставка перед первым узлом
return;
}
while (q && q->next!=p) // ищем узел, за которым следует p
q = q->next;
if ( q ) // если нашли такой узел,
AddAfter(q, NewNode); // добавить новый после него
}

Добавление узла перед заданным

Слайд 12

Проход по списку void print_list(PNode PHead) { PNode p = PHead;

Проход по списку

void print_list(PNode PHead) { PNode p = PHead;
printf("[ "); while(p !=

NULL) { printf("%d ", p->data); p = p->next; } printf("]\n"); }

PNode findNode (PNode PHead, int num)
{
PNode q = PHead;
// пока есть узел проверить нужное условие
while (q && ((q->data) != num))
q = q->next;
return q;
}

Поиск элемента в списке

Слайд 13

Удаление узла после заданного data next data next data nil data

Удаление узла после заданного

data

next

data

next

data

nil

data

next

data

next

data

nil

void deleteNode(PNode PHead, PNode DNode)
{
PNode q = PHead;
if

(Head == DNode)
Head = DNode->next; // удаляем первый элемент
else {
while (q && q->next != DNode) // ищем элемент
q = q->next;
if ( q == NULL ) return; // если не нашли, выход
q->next = DNode->next;
}
delete DNode; // освобождаем память
}

q

DNode

Слайд 14

void delete_list(PNode &PHead){ if (PHead != NULL){ delete_List(PHead->next); delete PHead; }

void delete_list(PNode &PHead){
if (PHead != NULL){
delete_List(PHead->next);
delete

PHead;
}
}

Удаление списка

Задание:

Удалить все элементы.
Найти средину списка.
Найти средину списка за один проход.