Существует множество решений этой проблемы, уже заявленных на этой странице.ИМХО фундаментальные вопросы:
Сколько времени занимает каждая операция push / pop?
Сколько места используется?В частности, каково наименьшее количество элементов, которые можно поместить в три стека, чтобы структура данных исчерпала пространство?
Насколько я могу судить, каждое решение ужеразмещенный на этой странице, либо может занять до линейного времени для push / pop, либо может исчерпать пространство с линейным числом пустых пространств.
В этом посте я буду ссылаться на решения, которые работают намного лучше,и я представлю самый простой.
Чтобы более подробно описать пространство решений, я буду ссылаться на две функции структуры данных следующим образом:
Структуракоторый требует O (f (n)) амортизированного времени для выполнения push / pop и не заканчивается места, если три стека не содержат по крайней мере n - O (g (n)) элементов будут называться (f, g) структура. Меньшие f и g лучше.Каждая структура, уже размещенная на этой странице, имеет n для времени или пространства.Я продемонстрирую (1, √n) структуру.
Все это основано на:
Майкл Л. Фредман и Дебора Л. Голдсмит, «Три стека», в Journal of Algorithms, том 17, выпуск 1, июль 1994 года, страницы 45-70
- Более ранняя версия появилась на 29-м ежегодном симпозиуме по основам компьютерных наук (FOCS) в 1988
Докторская диссертация Деборы Луизы Голдсмит из Калифорнийского университета, Сан-Диего, факультет электротехники / компьютерных наук в 1987 году, «Эффективное управление памятью для> = 3 стеков»
Они показывают, хотя я не буду представлять, структуру (log n / log S, S) для любого S. Это эквивалентно (t, n 1 / t )структура для любой т.Я покажу упрощенную версию структуры (1, √n).
Разделите массив на блоки размера Θ (√n).Блоки пронумерованы от 1 до Θ (√n), а номер блока называется его «адресом».Адрес может храниться в слоте массива вместо реального элемента.На элемент в данном блоке можно ссылаться с номером, меньшим, чем O (√n), и такой номер называется индексом.Индекс также помещается в слот массива.
Первый блок будет отведен для хранения адресов и индексов, и никакой другой блок не будет хранить никаких адресов или индексов.Первый блок называется каталогом .Каждый блок, не являющийся каталогом, будет пустым или содержит элементы только одного из трех стеков;то есть ни в одном блоке не будет двух элементов из разных стеков.Кроме того, каждый стек будет иметь не более одного блока, который частично заполнен - все остальные блоки, связанные со стеком, будут полностью заполнены или полностью пусты.
Пока существует пустой блок, операция push будетбыть разрешенным к любому стеку.Поп-операции всегда разрешены.При сбое операции push структура данных заполнена.В этот момент количество слотов, не содержащих элементов из одного из стеков, составляет не более O (√n): два частично заполненных блока из стеков, в которые не помещается, и один блок каталога.
Everyблок упорядочен таким образом, чтобы элементы ближе к передней части блока (нижние индексы) были ближе к нижней части стека.
Каталог содержит:
Триадреса для блоков в верхней части трех стеков или 0, если в конкретном стеке еще нет блоков
Три индекса для элемента в верхней части трех стеков, или0, если в конкретном стеке еще нет элементов.
Для каждого полного или частично полного блока адрес блока ниже, чем в том же стеке, или 0, если онсамый низкий блок в стеке.
Адрес свободного блока, называемого лидерным блоком, или 0, если свободных блоков нет
Для каждого свободного блока - адрес другого свободного блока или 0, если свободных блоков больше нет
Последние два представляют собой стек, хранящийся в виде односвязного списка свободных блоков. То есть, следуя адресам свободных блоков, начиная с блока-лидера, вы получите путь через все свободные блоки, заканчивающийся на 0.
Чтобы поместить элемент в стек, найдите его верхний блок и верхний элемент в этом блоке, используя каталог. Если в этом блоке есть место, положите его туда и верните.
В противном случае вытолкните стек свободных блоков, изменив адрес блока-лидера на адрес следующего свободного блока в стеке свободных блоков. Измените адрес и индекс для стека, чтобы он был адресом только что выскочившего свободного блока и 1 соответственно. Добавьте элемент в только что появившийся блок с индексом 1 и верните.
Все операции занимают O (1) время. Поп симметричный.