Этот вопрос помечен c
, поэтому для языка программирования c я согласен, что рекурсия - единственный путь.Однако, если поддерживаются анонимные функции первого класса, вы можете решить это без рекурсии.Некоторый псевдокод (с использованием лямбда-синтаксиса Haskell):
n = 0
f = \x -> 0 # constant function that always returns 0
while (not stack_empty) do
x = pop
n = n+1
f = \a -> if (a == n) then x else f(a)
middle = f(n/2) # middle of stack
# stack is empty, rebuilt it up to middle if required
for x in (n .. n/2) do push(f(x))
Обратите внимание: во время цикла while (рекурсивного) вызова f
нет.f(a)
в ветви else просто используется для создания новой (!) Функции, которая снова вызывается f
.
Предполагается, что в стеке есть 3 элемента 10, 20, 30 (снизу вверх)это в основном создает лямбда
(\a -> if a==1
then 30
else (\b -> if b==2
then 20
else (\c -> if c==3
then 10
else (\d -> 0)(c)
)
(b)
)
(a)
)
или чуть более читабельный
f(x) = if x==1 then 30 else (if x==2 then 20 else (if x==3 then 10 else 0))