- •А. С. Третьяков алгоритмы
- •Структуры данных Оглавление
- •2.1 Введение 20
- •4.1 Введение 69
- •5.1 Введение 87
- •Предисловие
- •Раздел I структуры данных
- •Глава 1. Массивы
- •1.1 Введение
- •1.2.1 Метод деления
- •1.2.2 Метод умножения
- •1.3.1 Открытое хеширование
- •1.3.2 Закрытое хеширование
- •1.4 Ассоциативный массив
- •1.5 Динамический массив
- •Глава 2. Списки
- •2.1 Введение
- •2.2 Связный список
- •2.3 Стек
- •2.4 Очередь
- •2.4.1 Реализация очереди с помощью массива
- •2.4.2 Реализация очереди с помощью указателей
- •Глава 3. Графы
- •3.1 Основные понятия и виды графов
- •3.2 Матрица смежности
- •3.3 Список смежности
- •3.4 Список ребер
- •3.5 Матрица инцидентности
- •Глава 4. Деревья
- •4.1 Введение
- •4.2 Двоичное дерево
- •4.3 Двоичное дерево поиска
- •4.4 Куча
- •4.5.1 Балансировка
- •4.5.2 Добавление узлов
- •4.5.3 Удаление узлов
- •Раздел II алгоритмы
- •Глава 5. Анализ сложности алгоритмов
- •5.1 Введение
- •5.2 Асимптотический анализ
- •Глава 6. Сортировка
- •6.1 Сортировка пузырьком
- •6.2 Сортировка выбором
- •6.3 Сортировка вставками
- •6.4 Сортировка Шелла
- •6.5 Быстрая сортировка
- •6.5.1 Разбиение массива
- •6.5.2 Рекурсивная сортировка частей массива
- •6.6 Сортировка слиянием
- •6.7 Гномья сортировка
- •6.8 Шейкерная сортировка
- •Глава 7. Поиск
- •7.1 Линейный поиск
- •7.2 Двоичный поиск
- •7.3 Интерполяционный поиск
- •Глава 8. Теория чисел
- •8.1 Алгоритм Евклида
- •8.1.1 Метод вычитания
- •8.1.2 Метод деления
- •8.2 Бинарный алгоритм вычисления нод
- •8.3 Быстрое возведение в степень
- •8.4 Решето Эратосфена
- •8.5 Решето Сундарама
- •Глава. 9 Графы
- •9.1 Поиск в ширину
- •9.2 Поиск в глубину
- •9.3 Алгоритм Дейкстры
- •9.4 Алгоритм Флойда – Уоршелла
- •9.5 Алгоритм Беллмана — Форда
1.4 Ассоциативный массив
Для доступа к элементам индексного массива используются обычные целые числа, называемые индексами. У ассоциативного массива (словаря) эту функцию выполняют ключи. Они, в отличие от индексов, могут быть заданы не только числовым типом данных, но и, например строковым или булевым. Каждому элементу ассоциативного массива соответствует пара «ключ-значение» (key, value), и на нем определены четыре базовые операции:
INSERT – операция добавления пары в массив;
REASSIGN – операция изменения существующей пары;
DELETE – операция удаления пары из массива;
SEARCH – операция поиска пары в массиве.
Данный список является стандартным, но все же он может быть дополнен некоторыми другими операциями. Также стоит отметить, что здесь приведены не общепринятые названия операций: обычно они зависят от языка программирования, на котором реализуются, да и вообще термин, обозначающий ассоциативный массив, варьируется в зависимости все от того же языка. Три наиболее распространенных названия:
словарь (Objective-C, .NET, Python, …);
карта (C++, Java, Haskell, …);
хеш (Perl, Ruby, …).
В одних языках программирования высокого уровня реализована встроенная поддержка ассоциативных массивов (Perl, PHP, Python, Ruby, JavaScript), в других они поставляются со специальными библиотеками (C++). Если же язык не имеет необходимых средств, то работу ассоциативного массива, как правило, можно имитировать при помощи других языковых компонентов.
В качестве примера объекта, организованного по принципу ассоциативного массива, можно привести тетрадь или базу данных, служащую для записи студентов, выписавших книги в университетской библиотеке, и пока не вернувших их. Ключами здесь будут названия книг, значениями – имена студентов. Так одно значение может соответствовать нескольким ключам (при этом ключи не повторяются), т. е. одну книгу может выписать только один студент, но этот же студент вправе выписать и другие книги.
Исходный код интерфейса ассоциативного массива, на тех языках программирования, в которых имеются встроенные средства (или подключаемые библиотеки) работы с этим типом данных, как правило, получается достаточно компактным и легко читаемым. Так реализация консольного приложения, обслуживающего университетскую библиотеку, на C++ сводится примерно к следующему варианту:
#include <map>
int main()
{
string name, book, number;
map <string, string> library;
do
{
cout<<"\n\nВыберите операцию:"<<endl;
cout<<"\n1. Добавить запись\n2. Найти запись\n";
cout<<"3. Удалить запись\n4. Вывести весь список\n5. Выйти\n\n";
cout<<"Номер операции > "; cin>>number;
if (number=="1")
{
cin.sync(); // очистка буфера
cout<<"Название книги > "; getline(cin, book);
cout<<"Имя студента > "; getline(cin, name);
library[book]=name;
cout<<"Добавлено..."<<endl<<endl;
}
else if (number=="2")
{
cin.sync(); // очистка буфера
cout<<"Книга > "; getline(cin, book);
map <string,
string>::const_iterator ifind=library.find(book);
if (ifind!=library.end())
{
cout<<"Книга: <"<<ifind->first<<"> | ";
cout<<"Студент: <"<<ifind->second<<">\n";
}
else cout<<"Данные отсутствуют";
}
else if (number=="3")
{
cin.sync(); // очистка буфера
cout<<"Книга > "; getline(cin, book);
library.erase(book);
cout<<"\nДанные удалены..."<<endl;
}
else if (number=="4")
{
map <string, string>::const_iterator i;
for(i=library.begin(); i!=library.end(); ++i)
{
cout<<"Книга: <"<<i->first<<"> | ";
cout<<"Студент: <"<<i->second<<">\n";
}
}
else if (number=="5") return 0;
else cerr<<"\nНеопознанная команда"<<endl;
} while (number!="5");
}
Здесь за весь функционал ассоциативного массива отвечает контейнер <map> библиотеки STL. Для его работы, вначале необходимо подключить файл map к программе посредством директивы #include:
#include <map>
Затем описать сам массив:
map <тип данных ключей, тип данных значений> название массива;
Для работы с массивом, контейнер <map> предоставляет определенное количество специальных функций, но в программе выше, использовались лишь некоторые из них.
Фактически ассоциативный массив базируется на другой структуре данных. В зависимости от языка программирования, он имеет различную реализацию. Например, в языках Ruby и Python ассоциативные массивы используют хеш-таблицу, а контейнер <map> в C++ выполнен на основе красно-чёрного дерева. Другие реализации оперируют сортированными и несортированными связными списками. Также возможен вариант, в котором используется массив фиксированного размера с указателем на последний заполненный элемент этого массива.
