Задача про розміщення ферзів. Дерево пошуку та його обхід
У задачі про ферзі роль магазина відіграє масив H. Збільшення номера вертикалі i, тобто перехід до наступного компонента масиву, разом із присвоюванням H[i]:=k відтворюють додавання до магазина нового елемента – пари (i, k). Цикл із заголовком
for k := 1 to n do
у процедурі deps задає перебирання вузлів-"братів"
що рівносильно послідовному вилученню з магазина попереднього брата з додаванням наступного.
Опишемо обхід дерева пошуку розміщень без застосування рекурсії. Розглянемо пересування, пов'язані з вузлами дерева. З допустимого вузла-листка ми одразу рухаємося до його батька, з недопустимого – до його брата. Пересування, пов'язані з кожним його проміжним вузлом, можна подати, як на рис.19.4.
Як бачимо, відвідувати проміжний вузол доводиться лише двічі – на початку та в кінці обходу дерева, коренем якого він є. Для того, щоб відрізнити ці два випадки, потрібні додаткові змінні. У разі розміщень ферзів перехід від вузла до його правого брата задається збільшенням H[i] на 1. Це рівносильне одночасному виштовхуванню вузла з магазина та додаванню його правого брата. Звідси випливає, що коли обробляється вузол глибини i, в магазині є лише по одному вузлу кожної глибини m, m i. Тому достатньо однієї додаткової змінної для кожної можливої глибини. Отже, означимо додатковий масив D того ж самого типу, що й масив H. Значенням D[i] стає 0, коли до вузла глибини i ми приходимо згори або зліва, та 1 – коли знизу.
Перехід до вузла знизу – це повернення до батька, і його умовою в задачі про ферзі є H[i]=n.
Повернення до кореня дерева означає кінець його обходу. Тому використаємо умову i=0 як умову закінчення пошуку. Отже, пошук повних допустимих розміщень ферзів має таке описання, яке по суті є тілом процедури пошуку:
i:=1; H[i]:=1; D[i]:=0;
while (i<>0) do
begin
if i=n then {обробка вузла-листка}
if test(H, i) then {друкування повного допустимого розміщення}
{ та повернення до батька незалежно від наявності братів}
begin writs(H, n); i:=i-1; {i>0!} D[i]:=1 end
else
if H[i]
else {повернення до батька – }
{піддерево, в якому він є коренем, вже обійшли}
begin i:=i-1; {i>0!} D[i]:=1 end