Реализация абстрактной структуры в виде неупорядоченного массива позволяет эффективно выполнять операцию вставки элемента в конец массива. Однако удаление, как правило, вынуждает сдвигать элементы, чтобы в массиве не было дыр. Поскольку элементы неупорядочены, операция извлечения сводится к последовательному перебору. Реализация абстрактной в виде упорядоченного массива вынуждает осуществлять сдвиг элементов при выполнении каждой операции вставки и удаления. В то же время, операция извлечения элементов позволяет применить эффективный бинарный поиск. При извлечении элемента также осуществляется последовательный поиск. Хотя линейные структуры довольно примитивны и малоэффективны, они оказываются полезными во многих приложениях.

В таких ситуациях эффективность не имеет большого значения, и на первый план выходят простота и ясность реализации. Даже если она велика, линейные структуры данных оказываются вполне приемлемыми, если не упорядочена, а операция удаления применяется редко. И все же самой лучшей реализацией таблиц наилучшей реализацией является нелинейное бинарное дерево. Если бинарное дерево поиска, содержащее l — узлов, имеет минимальную высоту, т.е. ее высота равна log2(l), оно позволяет эффективно реализовывать абстрактные в тех случаях, когда линейные структуры абсолютно неприемлемы. Эффективность первого шага операций извлечения, вставки и удаления в такой реализации сравнима с эффективностью бинарного поиска.

Кроме того, связанные списки позволяют легко изменять размеры. Такая реализация позволят эффективно выполнять очереди с приоритетами. Несмотря на определенные недостатки, для реализации вполне можно применять линейные структуры данных второй шаг операций вставки и удаления элементов фактически для этого нужно лишь изменить значения нескольких указателей (и выполнить переход к симметричному преемнику, если удаленный узел имел два дочерних узла). При этом никакого сдвига данных делать не нужно. Таким образом, реализация в виде бинарного дерева поиска объединяет в себе лучшие особенности обеих линейных реализаций.

Сбалансированное дерево поиска позволяет увеличить эффективность операций. Если операции вставки и удаления выполняются в произвольном порядке, высота бинарного дерева близка к минимальной. Однако следить за изменением высоты дерева и соответствующим снижением эффективности операций не стоит. Вместо этого лучше применить методы балансировки бинарного дерева поиска, которые позволяют сохранять высоту дерева близкой к величине log2.

Если размер задачи невелик, эффективность ее возможных решений практически одинакова. В частности, если размер мал, следует предпочесть ясную и понятную линейную реализацию. Вторая причина — эффективность. В некоторых ситуациях линейные структуры данных вполне эффективны. Например, для сценария, в котором доминируют операции вставки и обхода в произвольном порядке, лучше всего подходит именно линейная реализация. Для сценария, в котором доминирует операция извлечения, вполне приемлем упорядоченный массив, если максимальное количество элементов заранее известно.

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

Абстрактная структура

Абстрактная структура позволяет организовывать данные по ключу, облегчая поиск конкретного элемента по заданному значению. Следовательно, абстрактную следует применять, когда поиск в базе данных производится не по позиции, а по значению записи. Рассмотрим теперь абстрактный тип данных. Представьте себе человека, пришедшего в приемный покой больницы. Когда в больницу поступает новый пациент, регистратор вносит в базу данных запись об этом человеке. В дальнейшем эта запись будет извлечена медсестрами и врачами. Кроме того, регистратор должен следить за пациентами, поступившими в приемный покой, и решать, кому из них нужна помощь. Совершенно ясно, что регистратор обязан присвоить каждому пациенту определенный приоритет (priority). Тогда, освободившись, доктор может подойти к пациенту, имеющему наивысший приоритет. Абстрактный тип данных, необходимый для описания такой ситуации, должен указывать пациента, больше всех нуждающегося в помощи.

Рассмотрим еще один пример. Представьте себе список дел, которые вам предстоит выполнить на этой неделе. Допустим, это список состоит из таких пунктов. Послать поздравление с днем рождения тете Соне. Люди часто записывают задания в порядке их важности. Написать распорядок дня на воскресенье. Приоритет указывает, например, порядок обслуживания пациентов в приемном покое или очередность выполнения заданий. Какую величину можно использовать для вычисления приоритета. Для этого есть масса возможностей, начиная с простой нумерации. Для определенности будем считать, что наибольшее значение этой величины соответствует наивысшему приоритету.

Такой абстрактный тип данных называется очередью с приоритетами (priority queue). Говоря более формально, очередь с приоритетами — это абстрактный тип данных, предусматривающий следующие операции.

Линейный связанный список, содержит элементы, упорядоченные по убыванию, так что элемент, имеющий наивысший приоритет, находится в начале. Следовательно, операция просто вернет элемент, на который ссылается указатель, а затем установит его на следующий элемент. Однако операция должна обойти список с самого начала, прежде чем обнаружит позицию, подходящую для вставки. Таким образом, линейные реализации очереди с приоритетами страдают от тех же недостатков, что и линейные реализации абстрактной. В качестве альтернативной реализации очереди с приоритетами рассмотрим бинарное дерево поиска.

Итак, бинарное дерево поиска одинаково хорошо реализует как, так и очередь с приоритетами. Однако эти абстрактные типы данных используются в совершенно разных задачах. Некоторые приложения, использующие , в основном выполняют операции извлечения и обхода и поэтому не изменяют сбалансированности бинарного дерева поиска. В то же время, очередь с приоритетами не предусматривает операций извлечения и обхода, поэтому все операции вставки и удаления элементов изменяют форму соответствующего бинарного дерева поиска. Однако, если размер очереди с приоритетами известен заранее, имеет смысл выбрать реализацию кучи в виде массива. Эта реализация очень часто используется для представления очереди с приоритетами, но она не всегда подходит для работы с мыши.

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

Реализация кучи в виде массива содержит массив и счетчик. Представим кучу с помощью массив элементов кучи. Массив соответствует реализации дерева. (Для простоты будем считать, что куча содержит целые числа). В каком узле находится элемент, содержащий наибольший поисковый ключ? Поскольку поисковый ключ каждого ключа больше или равен поисковым ключам  своих дочерних узлов, наибольший поисковый ключ должен находиться в корне дерева. Единственная проблема — элемент, содержащийся в корне, как правило, находится не на своем месте. Такая структура называется полукучей. Таким образом, нам нужен способ, позволяющий преобразовать полукучу в настоящую кучу. Одна из стратегий решения этой задачи заключается в том, что элемент, содержащийся в корне, стекает (trickle down) по дереву, пока не достигнет узла, в котором он должен был бы находиться. Иными словами, элемент останется в первом же узле, поисковый ключ которого больше или равен поисковым ключам своих дочерних узлов. 

Для того чтобы осуществить этот план, сначала нужно сравнить поисковый ключ корня полукучи с поисковыми ключами его дочерних узлов. Если поисковый ключ корня меньше, чем поисковые ключи его дочерних узлов, элемент, содержащийся в корне нужно поменять местами с элементом, находящимся в наибольшем дочернем узле. Фактически, как только элементы, содержащиеся в корне и наибольшем дочернем узле, поменялись местами, узел становится корнем полукучи. Однако это не значит, что алгоритм неэффективен. Сначала попробуем определить, сколько элементов массива понадобится переставить в худшем случае Для реализации очереди с приоритетами в виде кучи необходимо знать заранее ее максимальный размер Какая из реализаций очереди с приоритетами лучше в виде кучи или в виде бинарного дерева поиска Если максимальный размер очереди известен заранее, реализация в виде кучи более эффективна. Поскольку куча является совершенным деревом, она всегда сбалансирована, что является ее несомненным преимуществом. Если бинарное дерево поиска сбалансировано, то эффективность обеих реализаций одинакова для очереди.