Стандартная библиотека шаблонов (STL)

Лабораторная работа № 8

Разработка приложений обработки абстрактных структур данных.

Цель работы

Овладеть практическими навыками работы с абстрактными структурами данных. Научиться формировать абстрактные структуры данных, освоить технику программирования операций над ними.

Краткие сведения из теории

Стек – это односвязный список, в котором можно удалять только первый элемент, а добавлять новый элемент – только перед первым. Таким образом, стек есть список, в котором возможно удалить только первый элемент, т. е. элемент, включенный в список последним, является головным (или первым). Иначе говоря, стек – это структура, у которой вход и выход совпадают.

На практике структура «стек» встречается очень часто: это и железнодорожный тупик, и пирамида, и рожок от автомата, и способ организации данных при работе программы на компьютере и т. д. Для стека существуют всего две операции – добавить элемент в стек и удалить элемент из стека. Эти операции принято оформлять соответственно в виде функций push() и pop(). Также реализуются операции вывода содержимого стека и определения глубины стека (количества элементов в стеке).

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

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

Стандартная библиотека шаблонов (STL).

STL обеспечивает общецелевые, стандартные классы и функции, которые реализуют наиболее популярные и широко используемые алгоритмы и структуры данных.

STL строится на основе шаблонов классов, и поэтому входящие в нее алгоритмы и структуры применимы почти ко всем типам данных.

Ядро библиотеки образуют три элемента: контейнеры, алгоритмы и итераторы.

Контейнеры (containers) - это объекты, предназначенные для хранения других элементов. Например, вектор, линейный список, множество.

В каждом классе-контейнере определен набор функций для работы с ними. Например, список содержит функции для вставки, удаления и слияния элементов.

Алгоритмы (algorithms) выполняют операции над содержимым контейнера. Существуют алгоритмы для инициализации, сортировки, поиска, замены содержимого контейнеров. Многие алгоритмы предназначены для работы с последовательностью (sequence), которая представляет собой линейный список элементов внутри контейнера.

Итераторы (iterators) - это объекты, которые по отношению к контейнеру играют роль указателей. Они позволяют получить доступ к содержимому контейнера примерно так же, как указатели используются для доступа к элементам массива.

В STL определены два типа контейнеров: последовательности и ассоциативные.

Ключевая идея для стандартных контейнеров заключается в том, что когда это представляется разумным, они должны быть логически взаимозаменяемыми. Пользователь может выбирать между ними, основываясь на соображениях эффективности и потребности в специализированных операциях. Например, если часто требуется поиск по ключу, можно воспользоваться map (ассоциативным массивом). С другой стороны, если преобладают операции, характерные для списков, можно воспользоваться контейнером list. Если добавление и удаление элементов часто производится в концы контейнера, следует подумать об использовании очереди queue, очереди с двумя концами deque, стека stack. По умолчанию пользователь должен использовать vector ; он реализован, чтобы хорошо работать для самого широкого диапазона задач.

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

В STL определены следующие классы-контейнеры (в угловых скобках указаны заголовочные файлы, где определены эти классы):

  • bitset - множество битов <bitset.h>
  • vector - динамический массив <vector.h>
  • list - линейный список <list.h>
  • deque - двусторонняя очередь <deque.h>
  • stack - стек <stack.h>
  • queue - очередь <queue.h>
  • priority_queue - очередь с приоритетом <queue.h>
  • map - ассоциативный список для хранения пар ключ/значение, где с каждым ключом связано одно значение <map.h>
  • multimap - с каждым ключом связано два или более значений <map.h>
  • set - множество <set.h>
  • multiset - множество, в котором каждый элемент не обязательно уникален <set.h>

Итераторы:

  • begin() - указывает на первый элемент
  • end() - указывает на элемент, следующий за последним
  • rbegin() - указывает на первый элемент в обратной последовательности
  • rend() - указывает на элемент, следующий за последним в обратной последовательности

Доступ к элементам:

  • front() - ссылка на первый элемент
  • back() - ссылка на последний элемент
  • operator [](i) - доступ по индексу без проверки
  • at(i) - доступ по индексу с проверкой

Включение элементов:

  • insert(p, x) - добавление х перед элементом, на который указывает р
  • insert(p, n, x) - добавление n копий х перед р
  • insert(p, first, last) - добавление элементов из [first:last] перед р
  • push_back(x) - добавление х в конец
  • push_front(x) - добавление нового первого элемента (только для списков и очередей с двумя концами)

Удаление элементов:

  • pop_back() - удаление последнего элемента
  • pop_front() - удаление первого элемента (только для списков и очередей с двумя концами)
  • erase(p) - удаление элемента в позиции р
  • erase(first, last) - удаление элементов из [first:last]
  • clear() - удаление всех элементов

Другие операции:

  • size() - число элементов
  • empty() - контейнер пуст
  • capacity() - память, выделенная под вектор (только для векторов)
  • reserve(n) - выделяет память для контейнера под n элементов
  • resize(n) - изменяет размер контейнера (только для векторов, списков и очередей с двумя концами)
  • swap(x) - обмен местами двух контейнеров
  • ==, !=, < операции сравнения

Операции присваивания:

  • operator =(x) - контейнеру присваиваются элементы контейнера х
  • assign(n, x) - присваивание контейнеру n копий элементов х (не для ассоциативных контейнеров)
  • assign(first, last) - присваивание элементов из диапазона [first:last]

Ассоциативные операции:

  • operator [](k) - доступ к элементу с ключом k
  • find(k) - находит элемент с ключом k
  • lower_bound(k) - находит первый элемент с ключом k
  • upper_bound(k) - находит первый элемент с ключом, большим k
  • equal_range(k) - находит lower_bound (нижнюю границу) и upper_bound (верхнюю границу) элементов с ключом k

Манипулирование контейнером, сортировка, поиск в нем и тому подобное возможно с помощью глобальных функций файла - заголовка <algorithm.h>.

Порядок выполнения работы

Написать программу, которая работает со структурой данных согласно варианту задания. Управление работой программы происходит через текстовое меню, содержащее все допустимые операции.

Наши рекомендации