Обход дерева

Обход дерева (известный также как поиск по дереву) — вид обхода графа[англ.], обусловливающий процесс посещения (проверки и/или обновления) каждого узла структуры дерева данных ровно один раз. Такие обходы классифицируются по порядку, в котором узлы посещаются. Алгоритмы в статье относятся к двоичным деревьям, но могут быть обобщены и для других деревьев.

Типы

В отличие от связных списков, одномерных массивов и других линейных структур данных, которые канонически обходятся в линейном порядке, деревья можно обходить различными путями. Деревья можно обходить «в глубину» или «в ширину». Существует три основных способа обхода «в глубину»

Структуры данных для обхода дерева

Обход дерева итеративно проходит по всем узлам согласно некоторому алгоритму. Поскольку из данного узла имеется более одного следующего узла (это не линейная структура данных), то, в предположении последовательных вычислений (а не параллельных), некоторые узлы должны быть отложены, то есть запомнены некоторым способом для дальнейшего посещения. Часто это делается с помощью стека (LIFO = последний вошёл — первый вышел) или очереди (FIFO = первый вошёл — первым вышел). Так как дерево самореферентная (ссылающаяся на себя, определённая рекурсивно) структура данных, обход может быть определён рекурсией или, более тонко, корекурсией естественным и ясным образом. В этих случаях отложенные узлы запоминаются либо явно в обычном стеке, либо неявно в стеке вызовов, либо явно в очереди.

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

Поиск в глубину

Эти поиски называются поиском в глубину ввиду того, что дерево поиска проходится вниз насколько это можно на каждом потомке прежде чем переходить к следующей родственной ветке. Для двоичного дерева они определяются как операции обработки вершины рекурсивно в каждом узле, начиная с корня. Алгоритм обхода следующий[2] [3]

Основной рекурсивный подход для обхода (непустого) бинарного дерева: Начиная с узла N делаем следующее:

(L) Рекурсивно обходим левое поддерево. Этот шаг завершается при попадании опять в узел N.

(R) Рекурсивно обходим правое поддерево. Этот шаг завершается при попадании опять в узел N.

(N) Обрабатываем сам узел N.

Эти шаги могут быть проделаны в любом порядке. Если (L) осуществляется перед (R), процесс называется обходом слева направо, в противном случае — обходом справа налево. Следующие методы показывают обходы слева направо:

Прямой обход (NLR)

Прямой обход: F, B, A, D, C, E, G, I, H.
  1. Проверяем, не является ли текущий узел пустым или null.
  2. Показываем поле данных корня (или текущего узла).
  3. Обходим левое поддерево рекурсивно, вызвав функцию прямого обхода.
  4. Обходим правое поддерево рекурсивно, вызвав функцию прямого обхода.

Центрированный обход (LNR)

Центрированный обход: A, B, C, D, E, F, G, H, I.
  1. Проверяем, не является ли текущий узел пустым или null.
  2. Обходим левое поддерево рекурсивно, вызвав функцию центрированного обхода.
  3. Показываем поле данных корня (или текущего узла).
  4. Обходим правое поддерево рекурсивно, вызвав функцию центрированного обхода.


В двоичном дереве поиска центрированный обход извлекает данные в отсортированном порядке.[4].

Обратный обход (LRN)

Обратный порядок: A, C, E, D, B, H, I, G, F.
  1. Проверяем, не является ли текущий узел пустым или null.
  2. Обходим левое поддерево рекурсивно, вызвав функцию обратного обхода.
  3. Обходим правое поддерево рекурсивно, вызвав функцию обратного обхода.
  4. Показываем поле данных корня (или текущего узла).

Последовательность обхода называется секвенциализацией дерева. Последовательность обхода — это список всех посещённых узлов. Ни одна из секвенциализаций согласно прямому, обратному или центрированному порядку не описывает дерево однозначно. Если задано дерево с различными элементами, прямой или обратный обход вместе с центрированным обходом достаточны для описания дерева однозначно. Однако прямой обход вместе с обратным оставляет некоторую неоднозначность в структуре дерева[5].

Дерево общего вида

Чтобы обойти любое дерево поиском в глубину, осуществляются рекурсивно следующие операции для каждого узла:

  1. Выполняется операция прямого обхода.
  2. Для каждого i от 1 до числа детей выполняем:
    1. Посещаем i-ого потомка, если он есть.
    2. Выполняем центрированную операцию.
  3. Выполняем операцию обратного обхода.

В зависимости от текущей задачи операции прямого, обратного или центрированного обхода могут быть пустыми, или вы можете хотеть лишь посетить конкретного потомка, так что эти операции опциональны. На практике может потребоваться более чем одна операция прямого, обратного или центрированного обхода. Например, когда осуществляется вставка в троичное дерево, операция прямого обхода выполняется путём сравнения элементов. Операция обратного обхода может потребоваться после этого для балансировки дерева.

Поиск в ширину

Уровневый порядок: F, B, G, A, D, I, C, E, H.

Деревья можно обходить также в порядке уровней, где мы посещаем каждый узел на уровне прежде чем перейти на следующий уровень. Такой поиск называется поиском в ширину (breadth-first search, BFS).

Другие виды

Существуют также алгоритмы обхода, которые не классифицируются ни как поиск в глубину, ни как поиск в ширину. Один из таких алгоритмов — метод Монте-Карло[англ.], который сосредотачивается на анализе наиболее обещающих ходов, основываясь на расширении дерева поиска при случайном выборе пространства поиска.

Приложения

Прямой обход при дублировании узлов и рёбер может сделать полный дубликат двоичного дерева. Это можно использовать для создания префиксного выражения (польской нотации) из деревья выражений[англ.], для чего обходим выражение в прямом порядке.

Центрированный обход наиболее часто используется в двоичных деревьев поиска, поскольку он возвращает значения из низлежащего множества в порядке, определяемом функцией сравнения, которая определяет двоичное дерево поиска.

Обратный обход при удалении или освобождении узлов может удалить или освободить всё бинарное дерево. Обход также образует постфиксное представление бинарного дерева.

Реализация

Поиск в глубину

Прямой обход

preorder(node)
  if (node = null)
    return
  visit(node)
  preorder(node.left)
  preorder(node.right)
iterativePreorder(node)
  if (node = null)
    return
  s ← empty stack
  s.push(node)
  while (not s.isEmpty())
    node ← s.pop()
    visit(node)
    //правый потомок заносится первым, так что левый потомок обрабатывается первым
    if (node.right ≠ null)
      s.push(node.right)
    if (node.left ≠ null)
      s.push(node.left)

Центрированный обход

inorder(node)
  if (node = null)
    return
  inorder(node.left)
  visit(node)
  inorder(node.right)
iterativeInorder(node)
  s ← empty stack
  while (not s.isEmpty() or node ≠ null)
    if (node ≠ null)
      s.push(node)
      node ← node.left
    else
      node ← s.pop()
      visit(node)
      node ← node.right

Обратный обход

postorder(node)
  if (node = null)
    return
  postorder(node.left)
  postorder(node.right)
  visit(node)
iterativePostorder(node)
  s ← empty stack
  lastNodeVisited ← null
  while (not s.isEmpty() or node ≠ null)
    if (node ≠ null)
      s.push(node)
      node ← node.left
    else
      peekNode ← s.peek()
      // если правый потомок существует и обход пришёл из левого потомка, двигаемся вправо
      if (peekNode.right ≠ null and lastNodeVisited ≠ peekNode.right)
        node ← peekNode.right
      else
        visit(peekNode)
        lastNodeVisited ← s.pop()

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

Центрированный обход Морриса с помощью прошивки

Двоичное дерево прошивается путём присвоения каждому левому указателю потомка (который в противном случае всегда пуст = null) указателя на предшественника узла в центрированном порядке (если таковой существует), а каждому правому указателю потомка (который в противном случае всегда пуст) указателя на следующий узел в центрированном порядке (если таковой существует).

Преимущества:

  1. Избегаем рекурсии, которая использует стек вызовов и расходует память и время.
  2. Узел хранит запись своего родителя.

Недостатки:

  1. Дерево более сложно.
  2. Мы можем сделать только один шаг обхода в один момент времени.
  3. Больше возможность ошибок, когда оба потомка отсутствуют и оба указателя узла указывают на предков.

Обход Морриса является имплементацией центрированного обхода, использующей прошивку[6]:

  1. Создаются ссылки на потомков в центрированном порядке.
  2. Печатаются данные согласно этим ссылкам.
  3. Отменяются изменения для возвращения к исходному дереву.

Поиск в ширину

Ниже приведён псевдокод для простого, основывающегося на очереди, поуровневого обхода. Алгоритм требует пространство, пропорциональное максимальному числу узлов на уровнях. Эта величина может достигать половины всех узлов. Более эффективный по памяти подход для этого типа обхода может быть имплементирован с помощью поиска в глубину с итеративным углублением[англ.].

levelorder(root)
  q ← empty queue
  q.enqueue(root)
  while (not q.isEmpty())
    node ← q.dequeue()
    visit(node)
    if (node.left ≠ null)
      q.enqueue(node.left)
    if (node.right ≠ null)
      q.enqueue(node.right)
    void wide(TreeNode* root){
        std::queue<TreeNode*> q;
        q.push(root);
        TreeNode* node;
        while (!q.empty()){
            node = q.front();
            q.pop();
            visit(node);
            if (node->left)
                q.push(node->left);
            if (node->right)
                q.push(node->right);
        }
    }

Бесконечные деревья

Обход обычно осуществляется для деревьев с конечным числом узлов (а следовательно, с конечной глубиной и конечным коэффициентом ветвления), но также он может быть осуществлён для бесконечных деревьев. Такой обход представляет интерес, в частности, в функциональном программировании (для отложенных вычислений), так как бесконечные структуры данных можно часто легко определить и работать с ними, хотя они не могут быть (строго) вычислены, так как потребовалось бы бесконечное время. Некоторые конечные деревья слишком велики, чтобы представить их явно, такие как дерево игры[англ.] шахмат или го, так что имеет смысл работать с ними как с бесконечными.

Главное требование обхода — посетить все узлы. Для бесконечных деревьев простые алгоритмы это осуществить не могут. Например, если имеется двоичное дерево бесконечной глубины, поиск в глубину будет двигаться вдоль одной стороны (обычно — по левой стороне) дерева, никогда не посетив остальные вершины, и более того, центрированный или обратный обход никогда не посетит никакой узел, так как никогда не достигнет листа. Для контраста, обход в ширину (поуровневый) обходит двоичное дерево бесконечной глубины без проблем и более того, обходит любое дерево с ограниченным коэффициентом ветвления.

С другой стороны, если дано дерево глубины 2, в котором корень имеет бесконечное число детей, а каждый узел-ребёнок имеет двух детей, поиск в глубину посетит все узлы, так как он, обойдя внуков (детей второго уровня), передвигается к следующему узлу (в предположении, что это не обратный обход, при котором никогда не достигается корень). Для контраста, поиск в ширину никогда не доберётся до внуков, поскольку он должен перебрать сначала всех детей (1-го уровня).

Более сложный анализ времени работы может быть дан с помощью бесконечных порядковых чисел. Например, поиск в ширину в дереве глубины 2 (как выше) будет занимать ω·2 шагов — ω для первого уровня и другие ω для второго уровня.

Таким образом, простые поиски в глубину и в ширину не обходят любое бесконечное дерево и неэффективны на очень больших деревьях. Однако гибридные методы могут обходить любое (счётное) бесконечное дерево, главным образом через диагональный аргумент[англ.] («диагональ», комбинация вертикали и горизонтали, соответствует комбинации поиска в глубину и в ширину).

Конкретно, если дано бесконечно ветвящееся дерево бесконечной глубины, помечаем корень (), детей корня (1), (2), …, внуков (1, 1), (1, 2), …, (2, 1), (2, 2), …, и так далее. Узлы тогда находятся в один-к-одному соответствии с конечными (возможно пустыми) последовательностями положительных чисел, множество которых счётно и может быть упорядочено сначала по сумме элементов, а затем по лексикографическому порядку внутри последовательностей с данной суммой (только конечное число последовательностей даёт заданную сумму, так что все узлы достигаются; формально говоря, существует конечное число композиций заданного натурального числа, а именно 2n−1 композиций). Этот порядок задаёт обход дерева. Конкретно:

0: ()
1: (1)
2: (1, 1) (2)
3: (1, 1, 1) (1, 2) (2, 1) (3)
4: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1) (4)

и т. д..

Это может быть проинтерпретировано как отображение бесконечно глубокого двоичного дерева в такого вида дерево и применение поиска в ширину — заменяем рёбра «вниз», соединяющие родительский узел со вторым и далее потомками, с «правыми» рёбрами от первого потомка ко второму, от второго к третьему и т. д.. Тогда на каждом шаге мы двигаемся либо вниз (добавляется (, 1) в конец) или идём вправо (добавляем единицу к последнему числу) (за исключением корня, от которого можно идти только вниз), что показывает связь между бесконечным бинарным деревом и приведённой выше нумерацией. Сумма входов (без единицы) соответствует расстоянию от корня, что согласуется с 2n−1 узлов и глубиной n − 1 в бесконечном двоичном дереве (2 соответствует бинарности дерева).

Примечания

  1. Lecture 8, Tree Traversal. Дата обращения: 2 мая 2015. Архивировано 5 августа 2018 года.
  2. Архивированная копия. Дата обращения: 29 мая 2018. Архивировано 28 августа 2017 года.
  3. Preorder Traversal Algorithm. Дата обращения: 2 мая 2015. Архивировано 11 апреля 2019 года.
  4. Wittman, Todd Tree Traversal (PDF). UCLA Math. Дата обращения: 2 января 2016. Архивировано из оригинала 13 февраля 2015 года.
  5. Algorithms, Which combinations of pre-, post- and in-order sequentialisation are unique?, Computer Science Stack Exchange. Дата обращения: 2 мая 2015. Архивировано 12 февраля 2015 года.
  6. Morris, 1979.

Литература

  • Nell Dale, Susan D. Lilly. Pascal Plus Data Structures. — Fourth Edition. — Lexington, MA: D. C. Heath and Company, 1995.
  • Adam Drozdek. Data Structures and Algorithms in C++. — Second edition. — Brook/Cole. Pacific Grove, CA, 2001.
  • Кормен, Лейзерсон, Ривест, Штайн. Глава 12. Бинарные деревья поиска // Алгоритмы: построение и анализ. — 3-е. — СПб.: Диалектика, 2020. — С. 319—322. — 1328 с.

Ссылки

Read other articles:

Diskografi Austin MahoneMahone performing in 2012.Album studio1Video musik7Extended play1Singel4Album soundtrack1Promotional singles2 Austin Mahone adalah seorang artis rekaman Amerika. Diskografi nya terdiri dari satu album studio, satu album mini, empat singel, dua singel promosional, empat video musik, dan peran album lainnya. Album Album Studio Daftar album Judul Rincian album Junior Year [1] Rilis: 2014[2] Format: CD, digital download Label: Chase, Young Money, Cash Money...

 

2019 IIHF World Women's U18 ChampionshipTournament detailsHost country JapanVenue(s)1 (in 1 host city)Dates6–13 January 2019Teams8Final positionsChampions  Canada (5th title)Runner-up  United StatesThird place  FinlandFourth place RussiaTournament statisticsGames played22Goals scored98 (4.45 per game)Attendance9,031 (411 per game)Scoring leader(s) Elisa Holopainen (8 points)MVP Raygan KirkWebsiteiihf.com/en/events/20...

 

Voce principale: Taranto Football Club 1927. Associazione Sportiva TarantoStagione 1974-1975 Sport calcio Squadra Taranto Allenatore Luciano Aristei (1ª) Guido Mazzetti (2ª-38ª) Amministratore unico Giovanni Fico Serie B15º posto Coppa ItaliaPrimo turno Maggiori presenzeCampionato: Cazzaniga (36) Miglior marcatoreCampionato: Jacomuzzi (7) StadioSalinella 1973-1974 1975-1976 Si invita a seguire il modello di voce Questa voce raccoglie le informazioni riguardanti l'Associazione Sporti...

جريج فان أفرمت (بالهولندية: Greg Van Avermaet)‏  معلومات شخصية الميلاد 17 مايو 1985 (العمر 38 سنة)بلجيكا الطول 1.81 م (5 قدم 11 بوصة)* مركز اللعب ثاقب  [لغات أخرى]‏  الجنسية  بلجيكا الوزن 74 كـغ (163 رطل) الحياة العملية الدور دراج الفرق بي إم سي راسينغ (2011–2020)لوتو سود�...

 

この項目には、一部のコンピュータや閲覧ソフトで表示できない文字が含まれています(詳細)。 数字の大字(だいじ)は、漢数字の一種。通常用いる単純な字形の漢数字(小字)の代わりに同じ音の別の漢字を用いるものである。 概要 壱万円日本銀行券(「壱」が大字) 弐千円日本銀行券(「弐」が大字) 漢数字には「一」「二」「三」と続く小字と、「壱」「�...

 

Politics of Papua New Guinea The Crown Monarch Charles III Governor-General Bob Dadae Executive Cabinet Prime Minister James Marape Legislature National Parliament Speaker: Job Pomat Leader of the Opposition Political parties Elections Recent elections General: 201220172022 Judiciary National Court Supreme Court Administrative divisions Administrative divisions Regions Provinces Districts Local-level governments Foreign relations Department of Foreign Affairs and Trade Minister: Soroi Eoe Dip...

This article includes a list of general references, but it lacks sufficient corresponding inline citations. Please help to improve this article by introducing more precise citations. (June 2014) (Learn how and when to remove this message) Belize electricity supply by source Energy in Belize is based on four main sources: imported fossil fuels, biomass, hydro, and imported electricity. Energy sources Belize currently imports 100% of its fossil fuel use (Launchpad Consulting, 2003). Under the ...

 

1863-1865 U.S. Congress 38th United States Congress37th ←→ 39thUnited States Capitol (1861)March 4, 1863 – March 4, 1865Members52 senators184 representatives10 non-voting delegatesSenate majorityRepublicanSenate PresidentHannibal Hamlin (R)House majorityRepublicanHouse SpeakerSchuyler Colfax (R)SessionsSpecial: March 4, 1863 – March 14, 18631st: December 7, 1863 – July 4, 18642nd: December 5, 1864 – March 3, 1865 The 38th United States Congress was a meeting of the ...

 

Railway station in Myōkō, Niigata Prefecture, Japan Kita-Arai Station北新井駅Kita-Arai Station in July 2017General informationLocationYanaida-chō, Myōkō-shi, Niigata-ken 944-0008JapanCoordinates37°03′10″N 138°15′27″E / 37.0529°N 138.2575°E / 37.0529; 138.2575Elevation33.6 m (110 ft)[1]Operated by Echigo Tokimeki RailwayLine(s)■ Myōkō Haneuma LineDistance23.9 km from Myōkō-KōgenPlatforms1 side platformTracks1Other informatio...

نظرية العلاقات الدولية الواقعية الواقعية الكلاسيكية الجديدة الواقعية الجديدة الواقعية الكلاسيكية الواقعية الهجومية الواقعية الدفاعية المدرسة الأنجليزية المكاسب النسبية المكاسب المطلقة الواقعية الاستراتيجية الليبرالية النظرية المثالية نظرية السلام الديمقراطي اللي�...

 

Ormoy-le-DaviencomuneOrmoy-le-Davien – Veduta LocalizzazioneStato Francia RegioneAlta Francia Dipartimento Oise ArrondissementSenlis CantoneNanteuil-le-Haudouin TerritorioCoordinate49°12′N 2°58′E49°12′N, 2°58′E (Ormoy-le-Davien) Superficie3,95 km² Abitanti307[1] (2009) Densità77,72 ab./km² Altre informazioniCod. postale60620 Fuso orarioUTC+1 Codice INSEE60478 CartografiaOrmoy-le-Davien Modifica dati su Wikidata · Manuale Ormoy-le-Davien è un com...

 

У этого термина существуют и другие значения, см. Николаевка. ПосёлокНиколаевкаукр. Миколаївка 47°32′20″ с. ш. 30°45′10″ в. д.HGЯO Страна  Украина Статус районный центр Область Одесская область Район Николаевский район (Одесская область) Глава Зубик Николай Михай�...

Right of public access to land or bodies of water For the Nikola Šarčević album, see Freedom to Roam. Hikers at Kinder Downfall, Derbyshire, England. Kinder Scout was the site of a mass trespass in 1932. The freedom to roam, or everyman's right, is the general public's right to access certain public or privately owned land, lakes, and rivers for recreation and exercise. The right is sometimes called the right of public access to the wilderness or the right to roam. In Austria, Belarus, Est...

 

32nd edition of the Federation Cup Football tournament season 2010 Indian Federation CupBarabati Stadium hosted the final on 2 october 2010Tournament detailsCountryIndonesiaDates14 – 18 September (qualification rounds) 21 September – 2 October (main competition)Teams22 (total) 16 (main competition)Final positionsChampionsEast Bengal (7th title)Runner-upMohun BaganAFC CupEast BengalTournament statisticsMatches played33Top goal scorer(s)Ranti Martins Muritala Ali← 2009–102...

 

Vetenskapsåret 1927 1926  · 1927  · 1928Humaniora och kulturFilm · Konst · Litteratur · Musik · Radio · Serier · TeaterSamhällsvetenskap och samhälleEkonomi · Krig  · Politik  · SportTeknik och vetenskapMeteorologi · Vetenskap Händelser Astronomi Okänt datum - Belgaren Georges Lemaître påstår att Universum kommer från en enda uratom.[1] 29 juni - En total solförmörkelse inträffade över Sverige. Fysik Oktober ...

يفتقر محتوى هذه المقالة إلى الاستشهاد بمصادر. فضلاً، ساهم في تطوير هذه المقالة من خلال إضافة مصادر موثوق بها. أي معلومات غير موثقة يمكن التشكيك بها وإزالتها. (نوفمبر 2019) كأس أذربيجان 2000–01 تفاصيل الموسم كأس أذربيجان،  وكأس أذربيجان  النسخة 10  البلد أذربيجان  التار�...

 

Pour les autres articles nationaux ou selon les autres juridictions, voir Assemblée nationale. Assemblée nationale(mg) Antenimierampirenena IIIe législature de la IVe République Logo de l'Assemblée nationale.Présentation Type Chambre basse Corps Parlement de Madagascar Création 1960 Lieu Antananarivo, Tsimbazaza Durée du mandat 5 ans Présidence Président Justin Tokely (IRMAR) Élection 11 juillet 2024 Structure Membres 163 députés Composition actuelle.Données clé...

 

ملعب رينزو باربيرامعلومات عامةأسماء سابقة ملعب يتوريو (1932-1936)ملعب ميشيل ماروني (1936-1945)ملعب لا فافوريتا (1945-2002)لقب ملعب لا فافوريتا La Favoritaالاسم الكامل Stadio Comunale Renzo Barberaسمّي باسم رينزو باربيرا — Michele Marrone (en) العنوان Viale del Fante 11, I-90146 Palermo (بالإيطالية) المنطقة الإدارية باليرمو الب�...

Cet article est une ébauche concernant la Vienne. Vous pouvez partager vos connaissances en l’améliorant (comment ?) selon les recommandations des projets correspondants. Civraisien Maison traditionnelle à Savigné Pays France Région française Nouvelle-Aquitaine Département français Vienne Villes principales CivrayCouhé GençayCharrouxUsson-du-Poitou Production Céréalesprairieschâtaignesnoix Régions naturellesvoisines Pays de Lusignan et de VouilléPoitevinMontmorillonnais...

 

2008 single by the Human LeagueThe Things That Dreams Are Made OfSingle by the Human Leaguefrom the album Dare Released21 January 2008 (2008-01-21)Recorded1981Genre Synth-pop new wave Length8:57LabelHooj ChoonsSongwriter(s) Philip Oakey Philip Adrian Wright Producer(s)Martin RushentThe Human League singles chronology Love Me Madly? (2003) The Things That Dreams Are Made Of (2008) Night People (2010) The Things That Dreams Are Made Of is a song by English synth-pop band The Hum...