- •Блок 5.07.02 структури даних (масиви, списки, графи, дерева) Модуль 5.07.02.01 структури даних Указатели и ссылки.
- •Контрольные вопросы:
- •Что собой представляют указатели?
- •Как можно описать указатели на языке Паскаль? Отображения.
- •Контрольные вопросы:
- •Каково назначение отображения?
- •Назовите команды работы с отображениями.
- •Как реализовываются отображения? Стеки и рекурсивные процедуры.
- •Листинг . Рекурсивное решение задачи о ранце
- •Контрольные вопросы:
- •В чем состоит организация выполнения процедур?
- •Что такое адрес возврата?
- •Контрольные вопросы:
- •Каково назначение хеш-таблицы?
- •Что такое хеш-функция? Словари.
- •Контрольные вопросы:
- •Каково назначение словарей?
- •Какие есть способы представления словарей?
Блок 5.07.02 структури даних (масиви, списки, графи, дерева) Модуль 5.07.02.01 структури даних Указатели и ссылки.
Указатель (pointer) — это ячейка, чье значение указывает на другую ячейку. При графическом представлении структуры данных в виде схемы тот факт, что ячейка А является указателем на ячейку В, показывается с помощью стрелки от ячейки А к ячейке В.
Операционная система MS-DOS все адресуемое пространство делит на сегменты. Сегмент – это участок памяти размером 64 Кбайт. Для задания адреса необходимо определить адрес начала сегмента и смещение относительно начала сегмента.
В языке Pascal определен адресный тип Рointer – указатель. Переменные типа Рointer :
var
p: Рointer;
содержат адрес какого-либо элемента программы и занимают 4 байта, при этом адрес хранится как два слова, одно из них определяет сегмент, второе – смещение.
Постфикс в виде стрелки, направленной вверх, в Pascal используется как оператор разыменования, т.е. выражение p^ обозначает значение (типа ТипЯчейки) в ячейке, указанной p.
Переменную типа указатель можно описать другим способом:
Var p:^T;
- где р – ссылка на переменную типа Т; p^ - обозначение этой самой переменной.
Рассмотрим некоторые примеры работы с указателями:
Var
p1, p2: ^integer; (Здесь р1 и р2 - указатели)
p1:=NIL; p2:=NIL; (После выполнения этих операторов присваивания указатели не будут ссылаться ни на какой конкретный объект)
New(p1); New(p2);
Контрольные вопросы:
Что собой представляют указатели?
Как можно описать указатели на языке Паскаль? Отображения.
Отображение — это функция, определенная на множестве элементов (области определения) одного типа (будем обозначать его domaintype — тип области определения функции) и принимающая значения из множества элементов (области значений) другого типа, этот тип обозначим rangetype — тип области значений (конечно, типы domaintype и rangetype могут совпадать). Тот факт, что отображение М ставит в соответствие элемент d типа domaintype из области определения элементу r типа rangetype из области значений, будем записывать как M(d) = r.
Некоторые отображения, подобные square(i) = i2, легко реализовать с помощью функций и арифметических выражений языка Pascal. Но для многих отображений нет очевидных способов реализации, кроме хранения для каждого d значения M(d).
Например, для реализации функции, ставящей в соответствие работникам их недельную зарплату, требуется хранить текущий заработок каждого работника.
Команды роботы с отображениями:
1. MAKENULL(M). Делает отображение М пустым.
2. ASSIGN(M, d, r). Делает M(d) равным r независимо от того, как M(d) было определено ранее.
3. COMPUTE(M, d, r). Возвращает значение true и присваивает переменной r значение M(d), если последнее определено, и возвращает false в противном случае.
Во многих случаях тип элементов области определения отображения является простым типом, который можно использовать как тип индексов массивов. В языке Pascal типы индексов включают все конечные интервалы целых чисел, например 1..100 или 17..23, строковый тип, диапазоны символов, подобные 'A'...'Z", и нечисловые типы, например север, восток, юг, запад. В частности, в программах кодирования можно применить отображение crypt (шифратор) с множеством 'A'...'Z' и в качестве области определения, и в качестве области значений, так что сrур1(текст) будет кодом текста текст.
Такие отображения просто реализовать с помощью массивов, предполагая, что некоторые значения типа rangetype могут иметь статус "неопределен". Например, для отображения crypt, описанного выше, область значений можно определить иначе, чем 'A'...'Z и использовать символ '?' для обозначения "неопределен".
Тип MAPPING (Отображение) можно объявить следующим образом:
type
MAPPING = array[domaintype] of rangetype;
Отображения с конечной областью определения можно представить в виде списка пар (d1 ,r1), (d2, r2), ..., (dk, rk), где d1, d2 …dn - все текущие элементы области определения, a r1, r2, ..., rk — значения, ассоциированные с rf; (t = 1, 2, ..., k). Далее можно использовать любую реализацию списков.
Абстрактный тип данных MAPPING можно реализовать как список типа elementtype, если сделано объявление
type
elementtype = record
domain: domain type
range: rangetype
end;
и затем объявлен тип MAPPING так, как мы ранее объявляли тип LIST (элементов типа elementtype), и в соответствии с той реализацией списков, которую мы выбрали.