Опубликован: 06.09.2005 | Доступ: свободный | Студентов: 12780 / 1211 | Оценка: 3.98 / 3.46 | Длительность: 12:50:00
ISBN: 978-5-9556-0025-3
Лекция 12:

Алгоритмы на графах и деревьях

Обход в ширину

Последовательность обхода
  1. Пометить вершину 0-го уровня (корень дерева).
  2. Пометить все вершины 1-го уровня.
  3. Пометить все вершины 2-го уровня.
  4. ...
Последовательность нумерации вершин при синтаксическом обходе дерева

Рис. 12.4. Последовательность нумерации вершин при синтаксическом обходе дерева

Замечание: Этот алгоритм может быть естественным образом распространен и на случай произвольного корневого дерева.

Алгоритм WideOrder
  1. Занести в очередь5См. лекцию 9. корень дерева.
  2. Пока очередь не станет пустой, повторять следующие действия:
    1. удалить первый элемент из головы очереди;
    2. добавить в хвост очереди всех потомков удаленной вершины.
Реализация

Для простоты реализации вновь пополним структуру дерева полем next:ukaz, которое будет служить для связки очереди:

head:= root;
tail:= root;
k:= 0;
repeat
	tail^.next:= head^.left;
	if head^.left<>nil then tail:= tail^.next;
	tail^.next:= head^.right;
	if head^.right<>nil then tail:= tail^.next;
	inc(k);
	head^.znachenie:= k;	{можно write(head^.znachenie);}
	head:= head^.next
until head = nil;
Последовательность нумерации вершин при обходе дерева в ширину

Рис. 12.5. Последовательность нумерации вершин при обходе дерева в ширину

Древесная сортировка

Задача. Упорядочить заданный набор (возможно, с повторениями) некоторых элементов (чисел, слов, т.п.).

Алгоритм TreeSort
  1. Для сортируемого множества элементов построить дерево двоичного поиска:
    • первый элемент занести в корень дерева;
    • для всех остальных элементов: начать проверку с корня; двигаться влево или вправо (в зависимости от результата сравнения с текущей вершиной дерева) до тех пор, пока не встретится такой же элемент, либо пока не встретится nil. Во втором случае нужно создать новый лист в дереве, куда и будет записано значение нового элемента.
  2. Совершить синтаксический обход построенного дерева, печатая каждую встреченную вершину столько раз, сколько было ее вхождений в сортируемый набор.
Реализация

Мы приведем реализацию первого шага алгоритма, сортирующего числа (для элементов другой природы потребуется изменить только процесс считывания):

new(root);
read(f,root^.chislo);
root^.kol:= 1;
root^.left:= nil;
root^.right:= nil;
while not eof(f) do
  begin
    read(f,x);
    p:= root;
	while true do
      begin 
        if x = p^.chislo
        then begin inc(p^.kol);
            break
        end;

        if x > p^.chislo 
          then if p^.right <> nil
                 then p:= p^.right
               else begin new(p^.right);
                      p:= p^.right;
                      p^.chislo:= x;
                      p^.kol:= 1;
                      p^.left:= nil;
                      p^.right:= nil;
                      break
                    end
 
             (* x < p^.chislo *)
        else if p^.left <> nil
               then p:= p^.left
             else begin new(p^.left);
                      p:= p^.left;
                      p^.chislo:= x;
                      p^.kol:= 1;
                      p^.left:= nil;
                      p^.right:= nil;
                      break
                  end
      end;
end;
Евгения Поздеева
Евгения Поздеева
Ольга Стебакова
Ольга Стебакова

Вот фрагмент лекции 5 (статья 4):

Проверка множества на пустоту может быть осуществлена довольно просто:

pusto:= true;   for i:= 1 to N do 

if set_arr[i] then begin pusto:= false; break end; {мне кажется здесь должно быть так:

if set_arr[i]<>0 then begin pusto:= false; break end;}

Хотелось бы знать это ошибка в теории или я просто не поняла лекцию?