- •А.Н. Горитов
- •Учебное пособие
- •Учебное пособие
- •Введение
- •1 Введение в предмет
- •1.1 Непрерывная и дискретная информация
- •1.2 Данные и эвм
- •1.3 Объекты предметной области
- •1.4 Представление информации об объектах
- •1.5 Абстрактные алфавиты. Кодирование
- •2 Основные типы и структуры данных эвм
- •2.1 Архитектурные особенности эвм, наиболее существенные для представления данных
- •2.2 Основные понятия о типах и структурах данных
- •2.3 Массивы
- •2.4 Строки
- •2.5 Записи
- •2.6 Записи с вариантами
- •2.7 Множества
- •3 Последовательный файл
- •3.1 Основные свойства последовательных файлов
- •3.2 Сортировка последовательных файлов
- •4 Полустатические структуры
- •4.1 Стек, очередь и дек как полустатические структуры
- •4.2 Представление полустатических структур с помощью массивов
- •5 Линейные динамические структуры
- •5.1 Основные свойства динамических структур
- •5.2 Реализация связного списка массивом
- •5.3 Кольцевой связный список
- •5.4 Линейный двусвязный список
- •6 Представление динамических структур с помощью указателей
- •6.1 Указатели
- •6.2 Представление стека
- •6.3 Представление очереди
- •6.4 Ведение динамических списков с помощью указателей
- •6.5 Алгоритм составления кольцевого двусвязного списка
- •7 Древовидные структуры данных
- •7.1 Основные понятия и определения
- •7.2 Представление деревьев в эвм
- •7.3 Основные операции с бинарными деревьями
- •7.4 Сильно ветвящиеся деревья
- •8 Алгоритмы на графах
- •8.1 Машинное представление графов
- •8.2 Поиск в глубину в графе
- •8.3 Поиск в ширину в графе
- •8.4 Стягивающие деревья (каркасы)
- •8.5 Отыскание фундаментального множества циклов в графе
- •8.6 Эйлеровы пути в графе
- •8.7 Алгоритмы с возвратом
- •8.8 Нахождение кратчайших путей в графе
- •8.9 Кратчайшие пути от фиксированной вершины
- •8.10 Алгоритм Дейкстры
- •8.11 Пути в бесконтурном графе
- •Литература
6 Представление динамических структур с помощью указателей
6.1 Указатели
Характерная особенность списковых структур данных (связных списков, стеков, очередей и т.д.) – это способность изменять число элементов. Это число заранее не определено и хранить в памяти пустые элементы списка накладно.
Лучше использовать так называемое динамическое распределение памяти, т.е. выделять память для элемента списковой структуры в тот момент, когда этот элемент появляется во время выполнения программы, а не во время её компиляции. В этом случае транслятор выделяет фиксированный объем памяти для хранения адресов динамически размещаемых элементов, а не самих элементов. Эти адреса называются указателями или ссылками.
В современных языках программирования можно явно использовать указатели. Это дает возможность строить более разнообразные динамические структуры данных. В них память отводится только на время существования элемента и освобождается, когда элемент уничтожается. В дальнейшем эта область памяти может использоваться повторно.
Элементы, выделяемые динамически, не имеют имени, к ним нельзя обращаться стандартным путем. Доступ к динамическим переменным осуществляется с помощью указателей (ссылок), которые становятся определенными после создания динамического элемента программы.
Для динамического представления списков каждый элемент списка должен содержать кроме смысловой информации поле типа "указатель". Следовательно, в динамических списковых структурах всегда элементом является запись, одна из компонент которой имеет тип "указатель". В соответствии с эти описание элемента списка будет следующим:
TYPE TP = ^SP; SP = RECORD
INF : CHAR; { INF : T0 }
LINK : TP END;
6.2 Представление стека
Стек состоит из нескольких динамических областей памяти, причем указатель вышерасположенного элемента указывает на предыдущий элемент. Внешний указатель (указатель стека) должен указывать на верхний элемент стека (рис. 15).
I TOP
L_T__
I I
TOP
[link i r* ~L~_~_~_J
|
LINK |
|
|
1 |
|
|
LINK |
|
|
| |
|
LINK
NEW(K)
Рис. 15 Представление стека в виде линейного списка
NIL
Для организации и ведения стека должны быть предусмотрены два указателя: ТОР и К: VAR ТОР, К : ТР;
СН : CHAR; Для добавления элемента в стек необходимо:
образовать динамическую переменную по указателю К;
занести в неё нужную информацию;
в поле указателя нового элемента занести значение указателя ТОР;
указателю ТОР присвоить значение указателя К. NEW(K);
KMNF := СН;
KA.LINK := TOP;
TOP := К;
Для удаления элемента из стека достаточно:
прочитать информацию СН := TOPMNF;
в указатель ТОР занести указатель удаляемого элемента ТОР := TOPA.LINK;
Но в этом случае удаленный из стека элемент образует "мусор". Лучше удалить из памяти этот элемент, предварительно сохранив значение указателя ТОР: К := ТОР; ТОР := KA.LINK; СН := KMNF; DISPOSE(K);
Опять принцип обратности и зеркальности здесь выполняется. Формирование стека с самого начала. Стек из N элементов: ТОР := Nil; WHILE N > О DO BEGIN
NEW(K); READ(CH);
KMNF := CH;
KA.LINK := TOP;
TOP := K; N := N -1
END;
Выбор всех элементов стека (самостоятельно): REPEAT
К := ТОР;
ТОР := KA.LINK;
СН := KMNF; WRITE(CH);
DISPOSE(K); UNTIL TOP = NIL; или WHILE TOP <> NIL DO . . . ;
Сравнивая операции обработки элементов стека в последовательной памяти, обнаруживаем их идентичность (сравнение с массивами).
Однако в динамических структурах снимается проблема переполнения стека.