Скачать презентацию C 05 NEW DELETE ДИНАМИЧЕСКИЙ Скачать презентацию C 05 NEW DELETE ДИНАМИЧЕСКИЙ

cpp05.pptx

  • Количество слайдов: 122

C++ 05 C++ 05

NEW & DELETE NEW & DELETE

ДИНАМИЧЕСКИЙ МАССИВ ДИНАМИЧЕСКИЙ МАССИВ

ПОЛУСТАТИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ. ПРИЗНАКИ • имеют переменную длину и простые процедуры ее изменения; • ПОЛУСТАТИЧЕСКИЕ СТРУКТУРЫ ДАННЫХ. ПРИЗНАКИ • имеют переменную длину и простые процедуры ее изменения; • изменение длины структуры происходит в определенных пределах, не превышая какого-то максимального (предельного) значения.

ЛОГИЧЕСКИЙ УРОВЕНЬ Последовательность данных, связанная отношениями линейного списка. Доступ к элементу может осуществляться по ЛОГИЧЕСКИЙ УРОВЕНЬ Последовательность данных, связанная отношениями линейного списка. Доступ к элементу может осуществляться по его порядковому номеру ФИЗИЧЕСКОЕ ПРЕДСТАВЛЕНИЕ Последовательность слотов в памяти, где каждый следующий элемент расположен в памяти в следующем слоте (т. е. вектор)

СТЕКИ (ОЧЕРЕДИ LIFO) СТЕКИ (ОЧЕРЕДИ LIFO)

Стек - последовательный список с переменной длиной, включение и исключение элементов из которого выполняются Стек - последовательный список с переменной длиной, включение и исключение элементов из которого выполняются только с одной стороны списка, называемого вершиной стека. Другие названия стека - магазин и очередь LIFO (Last - In - First- Out ) Примеры: винтовочный патронный магазин, тупиковый железнодорожный разъезд для сортировки вагонов.

ОПЕРАЦИИ НАД СТЕКОМ Основные операции над стеком: • Начальное формирование стека • включение нового ОПЕРАЦИИ НАД СТЕКОМ Основные операции над стеком: • Начальное формирование стека • включение нового элемента (push) • исключение элемента из стека (pop). Вспомогательные операции: • определение текущего числа элементов в стеке; • очистка стека; • неразрушающее чтение элемента из вершины стека, которое может быть реализовано, как комбинация основных операций: x: =pop(stack); push(stack, x).

СХЕМА СТЕКА СХЕМА СТЕКА

Пустой стек; Последовательное включение в него элементов с именами 'A', 'B', 'C'; Последовательное удаление Пустой стек; Последовательное включение в него элементов с именами 'A', 'B', 'C'; Последовательное удаление из стека элементов 'C' и 'B'; Включение в стек элемента 'D'.

ПУСТОЙ СТЕК stk = NULL; ПУСТОЙ СТЕК stk = NULL;

ФОРМИРОВАНИЕ НОВОГО ЭЛЕМЕНТА cin>>Элем; t = new (node); (*t). elem = Элем; (*t). sled ФОРМИРОВАНИЕ НОВОГО ЭЛЕМЕНТА cin>>Элем; t = new (node); (*t). elem = Элем; (*t). sled = stk;

"НАСТРОЙКА" УКАЗАТЕЛЯ СТЕКА stk = t;

ПЕРВЫЙ ЭЛЕМЕНТ В СТЕКЕ ПЕРВЫЙ ЭЛЕМЕНТ В СТЕКЕ

Размещение в стеке второго элемента cin>>Элем 1; t = new (node); (*t). elem = Размещение в стеке второго элемента cin>>Элем 1; t = new (node); (*t). elem = Элем 1; (*t). sled = stk;

"Настройка" указателя стека stk = t;

В стеке два элемента В стеке два элемента

ПОСТРОЕНИЕ СТЕКА void POSTROENIE (node **stk) { node *t; int el; *stk = NULL; ПОСТРОЕНИЕ СТЕКА void POSTROENIE (node **stk) { node *t; int el; *stk = NULL; cin>>el; while (el!=0) { t = new (node); (*t). elem = el; (*t). sled = *stk; *stk = t; cin>>el; }}

ВКЛЮЧЕНИЕ ЗВЕНА В СТЕК Исходное состояние стека ВКЛЮЧЕНИЕ ЗВЕНА В СТЕК Исходное состояние стека

Создание нового элемента q = new (node); (*q). elem = Элем; Создание нового элемента q = new (node); (*q). elem = Элем;

Включение элемента в стек (*q). sled = stk; Включение элемента в стек (*q). sled = stk;

"Настройка" указателя вершины стека stk = q;

ДОБАВЛЕНИЕ void W_S (node **stk, int el) { node *q; q = new (node); ДОБАВЛЕНИЕ void W_S (node **stk, int el) { node *q; q = new (node); (*q). elem = el; (*q). sled = *stk; *stk = q; }

ПОСТРОЕНИЕ void POSTROENIE (node **stk) { int el; *stk = NULL; cin>>el; while (el!=0) ПОСТРОЕНИЕ void POSTROENIE (node **stk) { int el; *stk = NULL; cin>>el; while (el!=0) { W_S (stk, el); cin>>el; }}

УДАЛЕНИЕ ЗВЕНА ИЗ СТЕКА Исходный стек УДАЛЕНИЕ ЗВЕНА ИЗ СТЕКА Исходный стек

СОХРАНЕНИЕ УДАЛЯЕМОГО ЭЛЕМЕНТА klad = (*stk). elem; СОХРАНЕНИЕ УДАЛЯЕМОГО ЭЛЕМЕНТА klad = (*stk). elem;

"ПЕРЕНАСТРОЙКА" УКАЗАТЕЛЯ СТЕКА q = stk; stk = (*stk). sled;

ОЧИСТКА ПАМЯТИ delete q; ОЧИСТКА ПАМЯТИ delete q;

УДАЛЕНИЕ ЭЛЕМЕНТА ИЗ СТЕКА void YDALENIE (node **stk, int klad) { node *q; if УДАЛЕНИЕ ЭЛЕМЕНТА ИЗ СТЕКА void YDALENIE (node **stk, int klad) { node *q; if (*stk==NULL) cout<<"Стек пуст!n"; else { *klad = (**stk). elem; q = *stk; *stk = (**stk). sled; delete q; } }

ОЧЕРЕДИ (ОЧЕРЕДИ FIFO) ОЧЕРЕДИ (ОЧЕРЕДИ FIFO)

ЛОГИЧЕСКАЯ СТРУКТУРА ОЧЕРЕДИ Очередью FIFO (First - In - First- Out) называется последовательный список ЛОГИЧЕСКАЯ СТРУКТУРА ОЧЕРЕДИ Очередью FIFO (First - In - First- Out) называется последовательный список с переменной длиной, в котором включение элементов выполняется только с одной стороны списка (эту сторону часто называют концом или хвостом очереди), а исключение - с другой стороны (называемой началом или головой очереди)

ОПЕРАЦИИ НАД ОЧЕРЕДЬЮ Основные операции над стеком: • Начальное формирование стека • включение нового ОПЕРАЦИИ НАД ОЧЕРЕДЬЮ Основные операции над стеком: • Начальное формирование стека • включение нового элемента (push) • исключение элемента из стека (pop). Вспомогательные операции: • определение текущего числа элементов в стеке; • очистка стека; • неразрушающее чтение элемента из вершины стека, которое может быть реализовано, как комбинация основных операций: x: =pop(stack); push(stack, x).

СХЕМАТИЧНОЕ ИЗОБРАЖЕНИЕ ОЧЕРЕДИ СХЕМАТИЧНОЕ ИЗОБРАЖЕНИЕ ОЧЕРЕДИ

ФОРМИРОВАНИЕ ОЧЕРЕДИ Первый элемент в очереди r = new (node); (*r). elem = Элем; ФОРМИРОВАНИЕ ОЧЕРЕДИ Первый элемент в очереди r = new (node); (*r). elem = Элем; (*r). sled = NULL;

НАСТРОЙКА УКАЗАТЕЛЕЙ НАЧАЛА И КОНЦА ОЧЕРЕДИ no = r; ko = r; НАСТРОЙКА УКАЗАТЕЛЕЙ НАЧАЛА И КОНЦА ОЧЕРЕДИ no = r; ko = r;

СОЗДАНИЕ НОВОГО ЭЛЕМЕНТА ОЧЕРЕДИ r = new (node); (*r). elem = Элем 1; (*r). СОЗДАНИЕ НОВОГО ЭЛЕМЕНТА ОЧЕРЕДИ r = new (node); (*r). elem = Элем 1; (*r). sled = NULL;

НАСТРОЙКА УКАЗАТЕЛЯ НА КОНЕЦ ОЧЕРЕДИ (*ko). sled = r; ko = r; НАСТРОЙКА УКАЗАТЕЛЯ НА КОНЕЦ ОЧЕРЕДИ (*ko). sled = r; ko = r;

void POSTROENIE (node **no, node **ko) { node *r; int el; cin>>el; if (el!=0) void POSTROENIE (node **no, node **ko) { node *r; int el; cin>>el; if (el!=0) { r = new (node); (*r). elem = el; (*r). sled = NULL; *no = r; *ko = r; cin>> el; while (el!=0) { r = new (node); (*r). elem = el; (*r). sled = NULL; (**ko). sled = r; *ko = r; cin>>el; } } else { r = NULL; *no = r; *ko = r; }}

void VYVOD (node **no, node **ko) { node *r; cout<<

ДОБАВЛЕНИЕ ЗВЕНА К ОЧЕРЕДИ Заполнение добавляемого звена r = new (node); (*r). elem = ДОБАВЛЕНИЕ ЗВЕНА К ОЧЕРЕДИ Заполнение добавляемого звена r = new (node); (*r). elem = Элем; (*r). sled = NULL;

Присоединение звена к очереди (*ko). sled = r; Присоединение звена к очереди (*ko). sled = r;

"НАСТРОЙКА" УКАЗАТЕЛЯ НА КОНЕЦ ОЧЕРЕДИ ko = r;

void DOBAVLENIE (node **no, node **ko, int el) { node *r; r = new void DOBAVLENIE (node **no, node **ko, int el) { node *r; r = new (node); (*r). elem = el; (*r). sled = NULL; if (*no!=NULL) { (**ko). sled = r; *ko = r; } else { *no = r; *ko = r; }}

УДАЛЕНИЕ ЗВЕНА ИЗ ОЧЕРЕДИ УДАЛЕНИЕ ЗВЕНА ИЗ ОЧЕРЕДИ

Сохранение удаляемого элемента klad = (*no). elem; Сохранение удаляемого элемента klad = (*no). elem;

Сохранение указателя на удаляемый элемент и “перенастройка” указателя на начало очереди q = no; Сохранение указателя на удаляемый элемент и “перенастройка” указателя на начало очереди q = no; no = (*no). sled;

УДАЛЕНИЕ delete q; УДАЛЕНИЕ delete q;

void YDALENIE (node **no, node **ko, int klad) { node *q; if (*no==NULL) cout<< void YDALENIE (node **no, node **ko, int klad) { node *q; if (*no==NULL) cout<< "Удалить нельзя, так как очередь пуста!n"; else { *klad = (**no). elem; q = *no; *no = (**no). sled; delete q; } }

ОЧЕРЕДИ С ПРИОРИТЕТАМИ Порядок выборки элементов из таких очередей определяется приоритетами элементов. Приоритет в ОЧЕРЕДИ С ПРИОРИТЕТАМИ Порядок выборки элементов из таких очередей определяется приоритетами элементов. Приоритет в общем случае может быть представлен числовым значением, которое FIFO, и LIFO-очереди могут трактоваться как приоритетные очереди, в которых приоритет элемента зависит от времени его включения в очередь. При выборке элемента всякий раз выбирается элемент с наибольшим приоритетом. Возможны очереди с приоритетным включением - в которых последовательность элементов очереди все время поддерживается упорядоченной, т. е. каждый новый элемент включается на то место в последовательности, которое определяется его приоритетом, а при исключении всегда выбирается элемент из начала. Возможны и очереди с приоритетным исключением - новый элемент включается всегда в конец очереди, а при исключении в очереди ищется (этот поиск может быть только линейным) элемент с максимальным приоритетом и после выборки удаляется из последовательности.

ДЕКИ ДЕКИ

Дек - особый вид очереди. Дек (deq - double ended queue) - это такой Дек - особый вид очереди. Дек (deq - double ended queue) - это такой последовательный список, в котором как включение, так и исключение элементов может осуществляться с любого из двух концов списка. Частный случай дека - дек с ограниченным входом и дек с ограниченным выходом. Логическая и физическая структуры дека аналогичны логической и физической структуре кольцевой FIFO-очереди.

ОПЕРАЦИИ НАД ДЕКОМ • Формирование дека • включение элемента справа; • включение элемента слева; ОПЕРАЦИИ НАД ДЕКОМ • Формирование дека • включение элемента справа; • включение элемента слева; • исключение элемента справа; • исключение элемента слева; • определение размера; • очистка.

"НАЧАЛЬНАЯ" ПОЗИЦИЯ ДЕКА С ЗАГЛАВНЫМ ЗВЕНОМ

ИСКЛЮЧЕНИЕ ЗАГЛАВНОГО ЗВЕНА q = nd; nd = (*nd). sled; (*nd). pred = NULL; ИСКЛЮЧЕНИЕ ЗАГЛАВНОГО ЗВЕНА q = nd; nd = (*nd). sled; (*nd). pred = NULL;

 "НАСТРОЙКА" УКАЗАТЕЛЯ И ОЧИСТКА ПАМЯТИ delete q; kd = z;

void Built. Deck (node **nd, node **kd) // Построение дека на базе двунаправленного // void Built. Deck (node **nd, node **kd) // Построение дека на базе двунаправленного // списка с заглавным звеном. // *nd - указатель на начало дека. // *kd - указатель на конец дека. { node *q, *z; int el; // Построение заглавного звена. *nd = new(node); z = *nd; (**nd). pred = (**nd). sled = NULL; cout<<"Введите последовательность: n"; cin>>el; while (el!=0) { (*z). sled = new(node); (*((*z). sled)). pred = z; z = (*z). sled; (*z). sled = NULL; (*z). elem = el; cin>>el; } if ((**nd). sled!=NULL) { q = *nd; *nd = (**nd). sled; (**nd). pred = NULL; *kd = z; delete q; } else { delete *nd; *nd = *kd = NULL; }}

 ВСТАВКА ЗВЕНА В НАЧАЛО ДЕКА q = new(node); (*q). elem = Элем; (*q). ВСТАВКА ЗВЕНА В НАЧАЛО ДЕКА q = new(node); (*q). elem = Элем; (*q). sled = nd; (*q). pred = NULL; (*nd). pred = q; nd = q;

void Ins. Left (node **nd, node **kd, int el) // Вставка звена, содержащего элемент void Ins. Left (node **nd, node **kd, int el) // Вставка звена, содержащего элемент el, в дек слева. // *nd - указатель на начало дека. / / *kd - указатель на конец дека. { node *q; q = new(node); (*q). elem = el; if (*nd==NULL) { // Если дек пуст, то. . . *nd = q; (*q). sled = (*q). pred = NULL; *kd = q; } else { (*q). sled = *nd; (*q). pred = NULL; (**nd). pred = q; *nd = q; } }

ВСТАВКА ЗВЕНА В КОНЕЦ ДЕКА q = new(node); (*q). elem = Элем; (*q). sled ВСТАВКА ЗВЕНА В КОНЕЦ ДЕКА q = new(node); (*q). elem = Элем; (*q). sled = NULL; (*q). pred = *kd; (*kd). sled = q; *kd = q;

void Ins. Right (node **nd, node **kd, int el) // Добавление звена, содержащего элемент void Ins. Right (node **nd, node **kd, int el) // Добавление звена, содержащего элемент el, в дек справа. // *nd - указатель на начало дека. // *kd - указатель на конец дека. { node *q; q = new(node); (*q). elem = el; if (*kd==NULL) { // Если дек пуст, то. . . *nd = q; (*q). sled = (*q). pred = NULL; *kd = q; }else { (*q). sled = NULL; (*q). pred = *kd; (**kd). sled = q; *kd = q; } }

АЛГОРИТМ УДАЛЕНИЯ ЗВЕНА ДЕКА АЛГОРИТМ УДАЛЕНИЯ ЗВЕНА ДЕКА

"НАСТРОЙКА" УКАЗАТЕЛЕЙ q = nd; nd = (*nd). sled;

ОЧИСТКА ПАМЯТИ delete q; ОЧИСТКА ПАМЯТИ delete q;

void Del. Left (node **nd, node **kd, int *el) { node *q; if ((**nd). void Del. Left (node **nd, node **kd, int *el) { node *q; if ((**nd). sled!=NULL) { q = *nd; *el =(*q). elem; *nd = (**nd). sled; (**nd). pred = NULL; delete q; } else { q = *nd; *el =(*q). elem; *nd = *kd = NULL; delete q; cout<<"Дек пуст!n"; } }

"НАСТРОЙКА" УКАЗАТЕЛЕЙ q = kd; kd = (*kd). pred; (*kd). sled = NULL;

delete q; delete q;

void Del. Right (node **nd, node **kd, int *el) { node *q; if ((**kd). void Del. Right (node **nd, node **kd, int *el) { node *q; if ((**kd). pred!=NULL) { q = *kd; *el =(*q). elem; *kd = (**kd). pred; (**kd). sled = NULL; delete q; } else { q = *kd; *el =(*q). elem; *nd = *kd = NULL; delete q; cout<<"Дек пуст!n"; } }

ЛИНЕЙНЫЕ ОДНОНАПРАВЛЕННЫЕ СПИСКИ ЛИНЕЙНЫЕ ОДНОНАПРАВЛЕННЫЕ СПИСКИ

ОПРЕДЕЛЕНИЯ Список - это совокупность объектов, называемых элементами списка, в которой каждый объект содержит ОПРЕДЕЛЕНИЯ Список - это совокупность объектов, называемых элементами списка, в которой каждый объект содержит информацию о местоположении связанного с ним объекта

ЭЛЕМЕНТ СПИСКА, ЗВЕНО информационное поле, которое в общем случае может содержать произвольное количество полей ЭЛЕМЕНТ СПИСКА, ЗВЕНО информационное поле, которое в общем случае может содержать произвольное количество полей разных типов. Если значением переменной p является ссылка на элемент списка, то присоединяя к обозначению (*p) с помощью точки имя соответствующего поля, можно манипулировать со значением любого поля информационной части; ссылка на следующий элемент списка

struct node { int elem; //Информационный элемент звена списка node *sled; // Указатель на struct node { int elem; //Информационный элемент звена списка node *sled; // Указатель на следующее звено списка }; struct node *phead;

ОДНОНАПРАВЛЕННЫЕ СПИСКИ БЕЗ ЗАГЛАВНОГО ЗВЕНА ОДНОНАПРАВЛЕННЫЕ СПИСКИ БЕЗ ЗАГЛАВНОГО ЗВЕНА

ОПЕРАЦИИ НАД СПИСКАМИ начальное формирование списка (запись первой компоненты); добавление компоненты в конец списка; ОПЕРАЦИИ НАД СПИСКАМИ начальное формирование списка (запись первой компоненты); добавление компоненты в конец списка; определение первого элемента в линейном списке; чтение компоненты с заданным ключом; с заданным свойством; вставка компоненты в заданное место списка (обычно до компоненты с заданным ключом или после неё); исключение компоненты с заданным ключом из списка. упорядочивание узлов линейного списка в определенном порядке.

РАЗМЕЩЕНИЕ УКАЗАТЕЛЕЙ В ПАМЯТИ struct node *phead; struct node *t; РАЗМЕЩЕНИЕ УКАЗАТЕЛЕЙ В ПАМЯТИ struct node *phead; struct node *t;

РЕЗЕРВИРУЕТСЯ МЕСТО ДЛЯ ДИНАМИЧЕСКОГО ОБЪЕКТА phead = new (node); РЕЗЕРВИРУЕТСЯ МЕСТО ДЛЯ ДИНАМИЧЕСКОГО ОБЪЕКТА phead = new (node);

ОПРЕДЕЛЕНИЕ T t = phead; (*t). value = Элем; ОПРЕДЕЛЕНИЕ T t = phead; (*t). value = Элем;

ДОБАВЛЕНИЕ НОВОГО ЭЛЕМЕНТА (*t). next = new (node); ДОБАВЛЕНИЕ НОВОГО ЭЛЕМЕНТА (*t). next = new (node);

T СОДЕРЖИТ АДРЕС ПОСЛЕДНЕГО ЭЛЕМЕНТА t = (*t). next; T СОДЕРЖИТ АДРЕС ПОСЛЕДНЕГО ЭЛЕМЕНТА t = (*t). next;

ЗАВЕРШЕНИЕ ПОСТРОЕНИЯ СПИСКА (*t). next = NULL; (*t). value = Элем 1; ЗАВЕРШЕНИЕ ПОСТРОЕНИЯ СПИСКА (*t). next = NULL; (*t). value = Элем 1;

КОНЕЧНЫЙ СПИСОК #include<iostream. h> struct node { int value; node *next; }; void main КОНЕЧНЫЙ СПИСОК #include struct node { int value; node *next; }; void main () { int i; node *phead, *t; phead = new (node); t = phead; (*t). value = 1; (*t). next = new (node); t = (*t). next; (*t). value = 2; (*t). next = new (node); t = (*t). next; (*t). value = 6; (*t). next = new (node); t = (*t). next; (*t). value = 17; (*t). next = new (node); (*t). next = NULL; // Вывод содержимого информационных полей списка for (t=phead; t!=NULL; t=(*t). next) cout<<(*t). value << " "; }

СПИСОК С ЗАГЛАВНЫМ ЗВЕНОМ СПИСОК С ЗАГЛАВНЫМ ЗВЕНОМ

ДВА СПОСОБА ПОСТРОЕНИЯ Каждый новый элемент добавляется в начало или в конец списка. Каждый ДВА СПОСОБА ПОСТРОЕНИЯ Каждый новый элемент добавляется в начало или в конец списка. Каждый элемент добавляется в свое место в списке, например, так, чтобы обеспечить упорядоченность по возрастанию или убыванию.

РЕЗЕРВИРОВАНИЕ МЕСТА В ПАМЯТИ struct node *phead; struct node *t; РЕЗЕРВИРОВАНИЕ МЕСТА В ПАМЯТИ struct node *phead; struct node *t;

ВЫДЕЛЕНИЕ МЕСТА ДЛЯ ЭЛЕМЕНТА СПИСКА phead = new(node); ВЫДЕЛЕНИЕ МЕСТА ДЛЯ ЭЛЕМЕНТА СПИСКА phead = new(node);

ПРИСВОЕНИЕ ЗНАЧЕНИЯ T t = phead; ПРИСВОЕНИЕ ЗНАЧЕНИЯ T t = phead;

ПРИСВОЕНИЕ УКАЗАТЕЛЮ ЗАГЛАВНОГО ЗВЕНА NULL (*t). sled = NULL; ПРИСВОЕНИЕ УКАЗАТЕЛЮ ЗАГЛАВНОГО ЗВЕНА NULL (*t). sled = NULL;

СОЗДАНИЕ НОВОГО ОБЪЕКТА cin>>Число; while (Число != Числу, определяющему окончание ввода) { (*t). sled СОЗДАНИЕ НОВОГО ОБЪЕКТА cin>>Число; while (Число != Числу, определяющему окончание ввода) { (*t). sled = new (node); //Резервируем место для нового объекта.

ОПРЕДЕЛЯЕМ T t = (*t). sled; //Указатель t содержит адрес //расположения созданного объекта. ОПРЕДЕЛЯЕМ T t = (*t). sled; //Указатель t содержит адрес //расположения созданного объекта.

 РЕЗУЛЬТАТ ЗАПОЛНЕНИЯ ПОЛЕЙ (*t). elem = Число; //Заполняем поля объекта. (*t). sled = РЕЗУЛЬТАТ ЗАПОЛНЕНИЯ ПОЛЕЙ (*t). elem = Число; //Заполняем поля объекта. (*t). sled = NULL;

ОКОНЧАНИЕ cin>>Число; //Запрос на ввод следующего значения. } ОКОНЧАНИЕ cin>>Число; //Запрос на ввод следующего значения. }

void POSTROENIE (node **phead) // Построение списка с заглавным звеном. // *phead - указатель void POSTROENIE (node **phead) // Построение списка с заглавным звеном. // *phead - указатель на заглавное звено. { node *t; int el; // Вначале создадим заглавное звено *phead = new (node); t = *phead; (*t). sled = NULL; cout<<"Вводите элементы звеньев списка: "; cin>>el; while (el!=0) { (*t). sled = new (node); t = (*t). sled; (*t). elem = el; (*t). sled = NULL; cin>>el; }}

ПУСТОЙ ОДНОНАПРАВЛЕННЫЙ СПИСОК С ЗАГЛАВНЫМ ЗВЕНОМ ПУСТОЙ ОДНОНАПРАВЛЕННЫЙ СПИСОК С ЗАГЛАВНЫМ ЗВЕНОМ

УДАЛЕНИЕ СПИСКА ИЗ ПАМЯТИ УДАЛЕНИЕ СПИСКА ИЗ ПАМЯТИ

вводятся два указателя q и q 1, один из которых будет вводятся два указателя q и q 1, один из которых будет "опережать" другой (пусть q 1 опережает q); начальное значение q - это адрес расположения в памяти заглавного звена, а q 1 - адрес расположения первого элемента списка; цикл, пока q 1!=NULL, то есть пока q 1 "не доберется" до указателя последнего элемента списка; в теле цикла переместим указатели на следующую пару элементов списка (то есть для первого случая q будет содержать адрес первого звена списка, а q 1 - второго), и удалим элемент, который адресуется значением q; после выполнения цикла у нас останется только заглавное звено, адресуемое указателем phead. Его также нужно удалить.

void OCHISTKA (node **phead) //Удаление однонаправленного списка из памяти. // *phead - указатель на void OCHISTKA (node **phead) //Удаление однонаправленного списка из памяти. // *phead - указатель на заглавное звено списка. { struct node *q, *q 1; // Рабочие указатели. q = *phead; q 1 = (*q). sled; // Указатель q 1 "опережает" указатель q. while (q 1!=NULL) { q = q 1; q 1 = (*q 1). sled; delete q; } delete *phead; //Удаление заглавного звена. }

ПОИСК ЗВЕНА void POISK (node **phead, int el, node **Res) // Поиск звена с ПОИСК ЗВЕНА void POISK (node **phead, int el, node **Res) // Поиск звена с элементом el в списке, заданном указателем *phead. // В случае успешного поиска в *Res находится адрес // звена списка, содержащего элемент el, в случае неуспеха в *Res помещается NULL. { node *t; *Res = NULL; t = *phead; t = (*t). sled; while (t!=NULL && *Res==NULL) if ((*t). elem==el) *Res = t; else t = (*t). sled; }

ВКЛЮЧЕНИЕ ЗВЕНА 1 -Й СЛУЧАЙ. ПОСЛЕ ЗВЕНА, НА КОТОРОЕ УКАЗЫВАЕТ ЗАДАННАЯ ССЫЛКА. ВКЛЮЧЕНИЕ ЗВЕНА 1 -Й СЛУЧАЙ. ПОСЛЕ ЗВЕНА, НА КОТОРОЕ УКАЗЫВАЕТ ЗАДАННАЯ ССЫЛКА.

РЕЗЕРВИРУЕТСЯ МЕСТО ДЛЯ ДИНАМИЧЕСКОГО ОБЪЕКТА q = new (node); РЕЗЕРВИРУЕТСЯ МЕСТО ДЛЯ ДИНАМИЧЕСКОГО ОБЪЕКТА q = new (node);

 ЗАПОЛНЕНИЕ ИНФОРМАЦИОННОГО ПОЛЯ (*q). elem = el; ЗАПОЛНЕНИЕ ИНФОРМАЦИОННОГО ПОЛЯ (*q). elem = el;

ЗАПОЛНЕНИЕ ПОЛЯ УКАЗАТЕЛЯ ВСТАВЛЯЕМОГО ЭЛЕМЕНТА (*q). sled = (*Res). sled; ЗАПОЛНЕНИЕ ПОЛЯ УКАЗАТЕЛЯ ВСТАВЛЯЕМОГО ЭЛЕМЕНТА (*q). sled = (*Res). sled;

ИЗМЕНЕНИЕ УКАЗАТЕЛЯ У ПРЕДЫДУЩЕГО ЭЛЕМЕНТА (*Res). sled = q; ИЗМЕНЕНИЕ УКАЗАТЕЛЯ У ПРЕДЫДУЩЕГО ЭЛЕМЕНТА (*Res). sled = q;

void VSTAV (node **Res, int el) // Включение звена с информационным полем el //после void VSTAV (node **Res, int el) // Включение звена с информационным полем el //после звена, на которое указывает ссылка *Res. { node *q; q = new (node); (*q). elem = el; (*q). sled = (**Res). sled; (**Res). sled = q; }

ВКЛЮЧЕНИЕ ЗВЕНА 2 -Й СЛУЧАЙ. ПЕРЕД ЗВЕНОМ, НА КОТОРОЕ УКАЗЫВАЕТ ССЫЛКА. ВКЛЮЧЕНИЕ ЗВЕНА 2 -Й СЛУЧАЙ. ПЕРЕД ЗВЕНОМ, НА КОТОРОЕ УКАЗЫВАЕТ ССЫЛКА.

ВЫДЕЛЕНИЕ МЕСТА В ПАМЯТИ ДЛЯ НОВОГО ЗВЕНА q = new (node); ВЫДЕЛЕНИЕ МЕСТА В ПАМЯТИ ДЛЯ НОВОГО ЗВЕНА q = new (node);

ЗАПОЛНЕНИЕ ПОЛЕЙ НОВОГО ЭЛЕМЕНТА (*q). elem = (*Res). elem; (*q). sled = (*Res). sled; ЗАПОЛНЕНИЕ ПОЛЕЙ НОВОГО ЭЛЕМЕНТА (*q). elem = (*Res). elem; (*q). sled = (*Res). sled;

ВКЛЮЧЕНИЕ ЭЛЕМЕНТА В СПИСОК (*Res). elem = el; (*Res). sled = q; ВКЛЮЧЕНИЕ ЭЛЕМЕНТА В СПИСОК (*Res). elem = el; (*Res). sled = q;

void VSTAV 1 (node **Res, int el) //Включение звена с информационным полем el //перед void VSTAV 1 (node **Res, int el) //Включение звена с информационным полем el //перед звеном, на которое указывает *Res. { node *q; q = new (node); (*q). elem = (**Res). elem; (*q). sled = (**Res). sled; (**Res). elem = el; (**Res). sled = q; }

УДАЛЕНИЕ ЗВЕНА, РАСПОЛОЖЕННОГО ПОСЛЕ ЗВЕНА, НА КОТОРОЕ УКАЗЫВАЕТ ССЫЛКА. //Определение местоположения удаляемого звена q УДАЛЕНИЕ ЗВЕНА, РАСПОЛОЖЕННОГО ПОСЛЕ ЗВЕНА, НА КОТОРОЕ УКАЗЫВАЕТ ССЫЛКА. //Определение местоположения удаляемого звена q = (*Res). sled;

ИСКЛЮЧЕНИЕ УДАЛЯЕМОГО ЭЛЕМЕНТА ИЗ СПИСКА if (q!=NULL) //Если звено, после которого нужно удалять, // ИСКЛЮЧЕНИЕ УДАЛЯЕМОГО ЭЛЕМЕНТА ИЗ СПИСКА if (q!=NULL) //Если звено, после которого нужно удалять, // не является последним, то. . . { (*Res). sled = (*(*Res). sled;

ОЧИСТКА ПАМЯТИ delete q; } ОЧИСТКА ПАМЯТИ delete q; }

void YDALE (node **Res) // Удаление звена, расположенного после // звена, на которое указывает void YDALE (node **Res) // Удаление звена, расположенного после // звена, на которое указывает ссылка *Res. { node *q; q = (**Res). sled; if (q!=NULL) // Если звено, после которого нужно удалять, // не является последним, то. . . { (**Res). sled = (*(**Res). sled; delete q; } else cout<<"Звено с заданным элементом - последнее!n"; }

УДАЛЕНИЕ ЗВЕНА, НА КОТОРОЕ УКАЗЫВАЕТ ССЫЛКА //Определяется местоположение следующего за удаляемым элемента q = УДАЛЕНИЕ ЗВЕНА, НА КОТОРОЕ УКАЗЫВАЕТ ССЫЛКА //Определяется местоположение следующего за удаляемым элемента q = (*Res). sled;

"ПЕРЕПИСЫВАТСЯ" СЛЕДУЮЩИЙ ЭЛЕМЕНТ В УДАЛЯЕМЫЙ if (q!=NULL) { //Если удаляемое звено не является последним, то. . . (*Res). elem = (*q). elem; (*Res). sled = (*q). sled;

ОЧИСТКА ПЯМЯТИ delete q; } ОЧИСТКА ПЯМЯТИ delete q; }

УДАЛЯЕМЫЙ ЭЛЕМЕНТ - ПОСЛЕДНИЙ Найдем указатель на предпоследнее звено линейного списка с помощью двух УДАЛЯЕМЫЙ ЭЛЕМЕНТ - ПОСЛЕДНИЙ Найдем указатель на предпоследнее звено линейного списка с помощью двух вспомогательных указателей q 1 иq 2, перемещающихся по списку "параллельно другу", причем указатель q 2 "опережает" указатель q 1 на один шаг.

ПЕРЕД УДАЛЕНИЕМ q 1 = phead; q 2 = (*q 1). sled; //Инициализация указателей. ПЕРЕД УДАЛЕНИЕМ q 1 = phead; q 2 = (*q 1). sled; //Инициализация указателей. while (q 2!=Res) { q 1 = q 2; q 2 = (*q 2). sled; }

ПОСЛЕ УДАЛЕНИЯ (*q 1). sled = NULL; q 2 = NULL; delete (Res); ПОСЛЕ УДАЛЕНИЯ (*q 1). sled = NULL; q 2 = NULL; delete (Res);