Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТРПП. ЛЕКЦИИ! Готовимся к экзамену))).docx
Скачиваний:
12
Добавлен:
10.12.2018
Размер:
175.63 Кб
Скачать

Операция delete

Операция delete освобождает память, выделенную операцией new.

Примеры.

Продолжим предыдущий пример, освободим выделенную память:

delete uk_i;

delete uk_d;

delete [ kol_s ] uk_s;

где kol_s – количество символов в строке.

Тема 1.10. Динамические структуры

Цель изучения темы

  • познакомиться с различными динамическими структурами

  • научиться работать с динамическими структурами в языке С++

До сих пор все рассмотренные программы позволяли работать с массивами фиксированной длины, например массив из 100 элементов. В реальной жизни обычно требуется, чтобы программа могла принимать от 50 до нескольких тысяч элементов и при этом экономно использовала ресурсы компьютера. Такие задачи решаются при помощи динамических структур.

Динамические структуры способны увеличиваться и уменьшаться в процессе работы. Должен быть организовать доступ к каждому элементу динамической структуры.

Разновидности динамических структур

Динамические структуры строятся из динамических элементов.

Динамический элемент состоит из двух частей:

  • информационная часть – хранит значение элемента

  • указатели – это адреса одного или нескольких других динамических элементов

В простейшем случае динамический элемент имеет вид:

В данном случае информационная часть состоит из одного поля, которое используется для хранения одного целого числа, указатель – из указателя на один элемент.

Из динамических элементов формируется цепочка. Динамический элемент хранит адрес следующего динамического элемента.

Существует 5 основных видов динамических структур:

  • очередь

  • стек

  • список

  • двунаправленный список

  • дерево

Очередь

Очередь работает по тому же принципу, что и очередь в магазине: "первым пришел, первым ушел". Элементы добавляются в конец очереди, а берутся из начала. Для работы необходимо знать начало и конец очереди.

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

Стек

Стек работает по принципу "первым пришел, последним ушел". Элементы добавляются и берутся с одного конца, который называется вершина стека.

Список

Порядок работы с элементами списка не определен. Можно, например, вставить или убрать элемент из любой части списка.

Может использоваться кольцевой список, в котором соединены начало и конец.

Двунаправленный список

Двунаправленный список формируется из динамических элементов с двумя указателями.

Может использоваться кольцевой список, в котором начало и конец соединены.

Дерево

Дерево состоит из элементов, которые называются узлами или вершинами.

Узлы соединены направленными дугами X->Y (от Х к Y). X называется предшественником (родителем) Y. Y - называется потомком.

Дерево имеет одну вершину, которая не имеет предшественников. Она называется корнем дерева. Вершины, которые не имеют потомков, называются листьями.

Дерево может формироваться из динамических элементов с двумя указателями.

Примеры программ (фрагментов программ) для работы с динамическими структурами

Программа для организации очереди.

Задача. Создание очереди из произвольного количества целых положительных чисел. Признак окончания ввода - отрицательное число.

#include < iostream.h>

#include < conio.h>

/* Описание структурного элемента, info - информационное поле, next -указатель на следующий элемент. */

struct ELEM

{

int info;

ELEM *next;

};

void main()

{

// Указатели на элементы очереди: первый, последний, текущий, старый, новый

ELEM *nach, *tek, *old, *kon, *new_n;

int i=1;

nach=0;

kon=0;

cout << "\n Введите произвольное кол-во целых чисел";

cout << "\n признак окончания ввода - отрицательное число";

// Создается очередь из целых чисел

do

{

// Ввод числа

cout << "\n Введите целое число";

cin >> i;

if (i<=0) break; // Прекращение цикла

// Создание очередного элемента

new_n=new ELEM; /* Выделяется память под новый элемент, адрес выделенной памяти записывается в new_n */

new_n-> info=i; /* Присваивается значение информационному полю нового элемента*/

new_n-> next=0; /* Присваивается значение указателю нового элемента */

if (nach)

{ // Если очередь не пуста, очередной элемент добавляется в конец очереди

kon-> next=new_n;

kon=new_n;

}

else

{

/* Если очередь пуста, начало и конец очереди будут указывать на один и тот же элемент */

nach=new_n;

kon=new_n;

}

}

while (i> 0);

// Пример обработки элементов

// Элементы отображаются на экране и удаляются из очереди

while (nach)

{

old=nach;

cout << "\n элемент "<< nach-> info; // Выводим элемент на экран

nach=nach-> next; // Переходим к следующему элементу очереди

delete old; // Очищаем память, которую занимал первый элемент

}

getch();

}

Фрагмент программы для реализации стека

Задача. Создание стека из элементов 9, 10,... 16.

nach=0; // nach - вершина стека

for (i=9; i<=16; i++)

{

// Создание очередного элемента

new_n=new ELEM;

new_n-> info=i;

if (nach)

{ // Если стек не пуст, очередной элемент добавляется в вершину стека

new_n-> next=nach;

nach=new_n;

}

else

{ // иначе стек будет состоять из одного элемента

new_n-> next=0;

nach=new_n;

}

Программа для реализации упорядоченного двоичного дерева

Двоичное (бинарное) дерево – это дерево, у каждой вершины которого может быть только два потомка.

Двоичное дерево является самым простым видом дерева. В упорядоченном дереве большее значение располагается справа от вершины, а меньшие значения слева от вершины.

Задача. Построить двоичное упорядоченное дерево из чисел 5, 7, 3, 1, 4.

Первый элемент (5) помещается в корень дерева:

Берем следующий элемент (7). Так как 7 больше 5, помещаем его в правую ветвь от 5:

Берем следующий элемент (3). Так как 3 меньше 5, помещаем его в левую ветвь от 5:

Берем следующий элемент (1). Так как 1 меньше 5 и левая ветвь уже существует (элемент 3), будем сравнивать 1 и 3. 1 меньше 3, поэтому помещаем 1 в левую ветвь от 3.

Берем следующий элемент (4). Так как 4 меньше 5 и левая ветвь уже существует (элемент 3), будем сравнивать 4 и 3. 4 больше 3, поэтому помещаем 4 в правую ветвь от 3. В результате получаем бинарное дерево:

Пример программы "Бинарное дерево".

Для создания дерева будут использованы рекурсивные функции:

dob – для добавления элемента,

pech – для печати элемента дерева.

Элемент дерева будет иметь структуру

#include <iostream.h>

struct DEREVO

{

int info;

DEREVO * next_l;

DEREVO * next_r;

};

void dob (DEREVO * tek, int znach); // прототип функции dob

void pech (DEREVO *tek); // прототип функции pech

void main()

{

int i;

DEREVO *nach, *tek, *new_n;

nach=0;

cout << "\n Вводите значения вершин дерева, 0 - признак окончания ввода ";

do

{

cout << "\nВведите значение вершины";

cin >> i;

if (nach)

{ // Если дерево не пусто, вызывается функци dob

dob(nach, i);

}

else

{ // Если дерево пусто создается корень дерева

new_n=new DEREVO;

new_n-> info=i;

new_n-> next_l=0;

new_n-> next_r=0;

nach=new_n;

}

}

while (i);

pech(nach); // Печать

}

/* Рекурсивная функция dob

tek - указатель на текущую вершину дерева,

znach - значение, которое необходимо добавить в дерево.

Функция dob определяет, в какую ветвь нужно добавить новое значение; если znach меньше текущего значения, то производиться добавление в левую ветвь, иначе - в правую ветвь.

Если ветвь нельзя добавить (такая ветвь уже существует), то снова вызывается функция dob. */

void dob (DEREVO * tek, int znach)

{

int i1;

DEREVO *new_n;

i1=tek-> info;

// Если значение текущего элемента дерева меньше нового элемента

if (znach<i1)

{

if (tek-> next_l)

dob (tek->next_l,znach);

else

{

new_n=new DEREVO;

new_n-> info=znach;

new_n-> next_l=0;

new_n-> next_r=0;

tek-> next_l=new_n;

}

}

if (znach>i1)

{

if (tek-> next_r)

dob (tek-> next_r,znach);

else

{

new_n=new DEREVO;

new_n-> info=znach;

new_n-> next_l=0;

new_n-> next_r=0;

tek-> next_r=new_n;

}

}

}

// Рекурсивная функция pech.

void pech (DEREVO *tek)

{

if (tek)

{

pech(tek-> next_l);

cout << "\n\t" << tek-> info;

pech(tek-> next_r);

}

}