
- •Структуры и алгоритмы обработки данных
- •Алгоритмы. Основные определения
- •От задачи к программе
- •Написание программы.
- •Типы данных, структуры данных и абстрактные типы данных
- •Указатели и курсоры
- •Время выполнения программ
- •Измерение времени выполнения программы
- •Степень (порядок) роста
- •Вычисление времени выполнения программ
- •Линейные абстрактные типы данных атд «Список»
- •Реализация списков посредством массивов
- •Реализация списков с помощью указателей
- •Атд «Стек»
- •Атд «Очередь»
- •Реализация очередей с помощью циклических массивов
- •Нелинейные абстрактные типы данных Деревья
- •Порядок узлов
- •Прямой, обратный и симметричный обходы дерева
- •Помеченные деревья и деревья выражений
- •Представление деревьев с помощью массивов
- •Специальные виды множеств атд “Дерево двоичного поиска”
- •Атд "Словарь", основанный
- •Представление ориентированных графов
- •Атд для ориентированных графов
- •Задача нахождения кратчайшего пути
- •Int **c, // массив стоимостей
- •Int *d) // массив кратчайших
- •Остовные деревья минимальной стоимости
- •Обход графов
- •Поиск в ширину
- •Поиск в глубину
- •Сортировка
- •Простые схемы сортировки Метод «пузырька»
- •Сортировка вставками
- •Быстрая сортировка
- •Пирамидальная сортировка
- •«Карманная» сортировка
- •Порядковые статистики
- •Методы разработки алгоритмов. Типы алгоритмов
- •Алгоритмы «разделяй и властвуй» (метод декомпозиции)
- •Баланс подзадач
- •Динамическое программирование
- •Перемножение нескольких матриц
- •Шаг 1: строение оптимальной расстановки скобок
- •Шаг 2: рекуррентное соотношение
- •Шаг 3: вычисление оптимальной стоимости
- •Void MatrixChainOrder(int n, // кол-во матриц
- •Int p[], // размеры матриц
- •Int **s) // оптимальное k
- •Шаг 4: построение оптимального решения
- •Int **s, // таблица, полученная
- •Int I, // индексы
- •Когда применимо динамическое программирование?
- •Оптимальность для подзадач
- •Перекрывающиеся подзадачи
- •«Жадные» алгоритмы
- •"Жадные" алгоритмы как эвристики
- •Когда применим жадный алгоритм?
- •Принцип жадного выбора
- •Оптимальность для подзадач
- •Поиск с возвратом
- •Функции выигрыша
- •Метод ветвей и границ
- •Структуры данных и алгоритмы для внешней памяти
- •Внешняя сортировка
- •Хранение данных в файлах
- •Простая организация данных
- •Хешированные файлы
- •Индексированные файлы
- •Содержание
- •Глава I. Линейные абстрактные типы данных 31
- •Глава II. Сортировка 108
-
Линейные абстрактные типы данных атд «Список»
Списки являются чрезвычайно гибкой структурой, так как их легко сделать большими или меньшими, и их элементы доступны для вставки или удаления в любой позиции списка.
Списки также можно объединять или разбивать на меньшие списки.
Списки используются в программах информационного поиска, трансляторах программных языков, при моделировании различных процессов, для организации управления памятью и т.д.
-
В математике список представляет собой последовательность элементов определенного типа, который в общем случае будем обозначать как element_type (тип элемента).
-
представлять список как последовательность элементов разделенных запятыми: а1, а2, …, аn, где n>=0 и все аi имеют тип element_type.
Количество элементов n будем называть длиной списка.
Если n1, то а1 называется первым элементом, а аn – последним элементом списка.
В случае n=0 имеем пустой список, который не содержит элементов.
Важное свойство списка заключается в том, что его элементы можно линейно упорядочить в соответствии с их позицией в списке.
Мы говорим, что элемент аi предшествует элементу аi+1 если он не последний и аi следует за аi-1 если он не первый.
Также будем говорить, что элемент аi имеет позицию i.
Кроме того, существует позиция, следующая за последним элементом списка. Функция END(L) будет возвращать позицию, следующую за позицией n и n-элементном списке L.
Отметим, что позиция END(L), рассматриваемая как расстояние от начала списка, может изменяться при увеличении или уменьшении списка, в то время как другие позиции имеют неизменное фиксированное расстояние от начала списка.
Для формирования АТД на основе математического определения списка мы должны задать множество операторов, выполняемых над объектами типа LIST (список).
Обычно реализуют не все множество возможных операторов, а только некоторую его часть необходимую для работы данного приложения.
Рассмотрим некоторые типичные операторы.
Введем обозначения:
L – список объектов типа element_type,
x – объект этого типа,
p – позиция элемента в списке.
-
INSERT(x,p,L). Этот оператор вставляет объект х в позицию р в списке L, перемещая элементы от позиции р и далее в следующую, более высокую позицию.
Таким образом, если список L состоит из элементов а1, а2, …, аn , то после выполнения этого оператора он будет иметь вид а1, а2, …, ар-1 х, ар, …, аn.
Если р принимает значение END(L), то будем иметь а1, а2, …, аn ,х.
Если в списке L нет позиции р, то результат выполнения этого оператора не определен.
-
LOCATE(x,L). Эта функция возвращает позицию объекта х в списке L. Если в списке объект х встречается несколько раз, то возвращается позиция первого от начала списка объекта х. Если объекта х нет в списке, то возвращается END(L).
-
RETRIEVE(p,L). Эта функция возвращает элемент, который стоит в позиции р в списке L. Результат не определен если р>=END(L).
-
DELETE(p,L). Этот оператор удаляет элемент в позиции р списка L. Результат не определен если р>=END(L).
-
NEXT(p,L) и PREVIOUS(p,L). Эти функции возвращают соответственно следующую и предыдущую позиции от позиции р в списке.
Если р – последняя позиция в списке, то NEXT(p,L)=END(L).
Функция NEXT не определена, когда р=END(L).
Функция PREVIOUS не определена, если р=1.
Обе функции не определены, если в списке нет позиции р.
-
MAKENULL(L). Эта функция делает список L пустым и возвращает позицию END(L).
-
FIRST(L). Эта функция возвращает первую позицию в списке L. Если список пустой, то возвращается END(L).
-
PRINTLIST(L). Печатает элементы списка L в порядке их расположения.
Для реализации списков можно использовать несколько структур данных. Мы рассмотрим реализации списков с помощью массивов, указателей и курсоров.