Реализация запроса в дереве отрезков снизу — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Псевдокод)
Строка 1: Строка 1:
==Описание==
+
[[Файл:Down-up1.png|right|255px|thumb|Реализация запроса снизу вверх]]
Реализация запроса снизу вверх в дереве отрезков является, в отличие от реализации сверху вниз, итеративным методом.
+
 
 
==Алгоритм==
 
==Алгоритм==
[[Файл:Down-up1.png|right|350px|thumb|Реализация запроса снизу вверх]]
+
 
Будем рассматривать дерево отрезков с операцией нахождения минимального значения на отрезке(RMQ).<br>
+
Реализация запроса снизу вверх в дереве отрезков является, в отличие от реализации сверху вниз, итеративным методом. Будем рассматривать дерево отрезков с операцией нахождения минимального значения(RMQ).
Установим границы отрезка на соответствующие листья. Если элемент попавший на левую границу является правым сыном, то отрезаем его, левая граница перемещается на один элемент вправо; в другом случае левую границу не трогаем. Аналогично рассматриваем элемент попавший на правую границу (является ли этот элемент левым сыном). Затем устанавливаем границы отрезка на родительские элементы текущих границ. Отрезая элемент, мы считаем минимум из отрезанного и минимума на оставшемся отрезке. Закончим алгоритм, когда границы пересекутся.
+
 
 +
Установим границы отрезка на соответствующие листья. Если элемент, попавший на левую границу, является правым сыном, то вычисляем результат как минимум между предыдущем результатом и значением этого элемента. Левая граница перемещается на один элемент вправо. Иначе левую границу не трогаем. Аналогично действуем с элементом попавшим на правую границу (является ли этот элемент левым сыном). Затем устанавливаем границы отрезка на родительские элементы текущих границ. Продолжаем до тех пор, пока границы не пересекутся.
  
 
==Псевдокод==
 
==Псевдокод==
Псевдокод функции нахождения минимума на отрезке <tex>[left, right]</tex>.
 
  
   segmentMin(left, right)
+
Пусть дерево отрезков реализовано на массиве с индексацией элементов с 1.
       res = MAX_INT;  
+
 
       while left < right
+
  //Функция нахождения минимального элемента на отрезке <tex>[left, right]</tex>
         if isRightSon(left)
+
   Min(left, right)
             res = min(res, data[left]);
+
       result = +inf; //Присваиваем результату максимально возможное значение
             left = parent(left + 1);
+
       while (left < right) //Выполняем цикл до тех пор пока левая и правая граница не совпадут
 +
         if ((left) / 2) * 2 == left // Проверяем является ли левая граница правым сыном
 +
             result = min(result, left.data); // Если является то пересчитаем результат и перенесем левую границу
 +
             left = (left + 1) / 2;  
 
         else
 
         else
             left = parent(left);
+
             left = (left) / 2; // Если не является, то установим границу на родительский элемент текущей границы
         if isLeftSon(right)
+
         if ((right) / 2) * 2 + 1 == right // Аналогично проделываем операции с правой границей
             res = min(res, data[right]);
+
             result = min(result, right.data);
             right = parent(right - 1);
+
             right = (right - 1) / 2;
 
         else
 
         else
             right = parent(right);
+
             right = (right) / 2;
        if left == right
+
      if (left == right) // После окончания цикла проверяем совпали ли границы 
            res = min(res, data[left]);
+
        result = min(result, left.data); // Если надо пересчитываем результат
        return res;
+
       return result;
 
 
Функция <tex>parent()</tex> возвращает родителя аргумента.<br>
 
Функции <tex>isLeftSon(), isRightSon()</tex> возвращают является ли элемент правым или левым сыном соответственно.
 
Пусть дерево отрезков реализовано на массиве с индексацией элементов с 1.
 
 
 
  parent(vertex)
 
      return vertex / 2;
 
 
 
  isLeftSon(vertex)
 
      if parent(vertex) * 2 + 1 == vertex
 
        return true;
 
       return false;
 
  
 
==Ссылки==
 
==Ссылки==

Версия 14:20, 24 мая 2012

Реализация запроса снизу вверх

Алгоритм

Реализация запроса снизу вверх в дереве отрезков является, в отличие от реализации сверху вниз, итеративным методом. Будем рассматривать дерево отрезков с операцией нахождения минимального значения(RMQ).

Установим границы отрезка на соответствующие листья. Если элемент, попавший на левую границу, является правым сыном, то вычисляем результат как минимум между предыдущем результатом и значением этого элемента. Левая граница перемещается на один элемент вправо. Иначе левую границу не трогаем. Аналогично действуем с элементом попавшим на правую границу (является ли этот элемент левым сыном). Затем устанавливаем границы отрезка на родительские элементы текущих границ. Продолжаем до тех пор, пока границы не пересекутся.

Псевдокод

Пусть дерево отрезков реализовано на массиве с индексацией элементов с 1.

  //Функция нахождения минимального элемента на отрезке [math][left, right][/math]
  Min(left, right)
     result = +inf; //Присваиваем результату максимально возможное значение
     while (left < right) //Выполняем цикл до тех пор пока левая и правая граница не совпадут
        if ((left) / 2) * 2 == left // Проверяем является ли левая граница правым сыном
           result = min(result, left.data); // Если является то пересчитаем результат и перенесем левую границу
           left = (left + 1) / 2; 
        else
           left = (left) / 2; // Если не является, то установим границу на родительский элемент текущей границы
        if ((right) / 2) * 2 + 1 == right // Аналогично проделываем операции с правой границей
           result = min(result, right.data);
           right = (right - 1) / 2;
        else
           right = (right) / 2;
     if (left == right) // После окончания цикла проверяем совпали ли границы  
        result = min(result, left.data); // Если надо пересчитываем результат
     return result;

Ссылки

MAXimal :: algo :: Дерево отрезков

Дерево отрезков — Википедия

Визуализатор

Алгоритм