Nano Hash - криптовалюты, майнинг, программирование

соединять узлы на одном уровне бинарного дерева

Я видел несколько статей/страниц о том, как соединить узлы бинарного дерева, которые находятся на одном уровне, но ни одна из этих статей четко не объясняет процесс/алгоритм. Буду признателен, если кто-то возьмется за это. Код не обязателен, но объяснить его с помощью псевдо будет неплохо.

Для обсуждения давайте рассмотрим дерево как:

               0
           1        2
        3     4   5    6
    7                      9

В приведенном выше случае:

0 should point to null.
1 should point to 2.
3 should point to 4.
....
7 should point to 9.
9 should point to NULL.

Базовая древовидная структура:

class Tree {
  public:
    int data;
    Tree* left;
    Tree* right;
    Tree* next;
}

  • Вы можете перемещаться по дереву по уровням, используя алгоритм поиска в ширину, и на каждом уровне вы можете временно сохранить предыдущий узел. Тогда next из previous node будет узлом currently parsed. 17.01.2017
  • Да, используйте bfs или поиск в ширину, который проходит по слоям, так что в основном у вас будут узлы на одном уровне на одинаковом расстоянии от корня. 17.01.2017
  • @sameerkn, я понимаю. Не могли бы вы написать псевдокод, пожалуйста? 17.01.2017

Ответы:


1

Есть интересный подход, который не использует дополнительную память, что является своего рода индуктивным:

  1. Первый уровень уже подключен (у него только один узел)

  2. Допустим, уровень i подключен. Затем для подключения уровня i+1 выполните следующие действия:

    а) Инициализируйте узел lst (просто промежуточная переменная, которую мы будем использовать позже) в null

    б) Начните с первого узла на уровне i.

    c) Пройдите узлы на уровне i, начиная с первого узла. Обратите внимание, что вы можете легко перемещаться по узлам на уровне i, потому что он уже подключен, поэтому в каждом узле у вас есть одноуровневые указатели.

    г) Для каждого узла на уровне i сначала посмотрите на его левого потомка, а затем на его правого потомка. Для каждого дочернего элемента, который не равен нулю, если lst не равно null, соедините lst с этим дочерним элементом. Затем установите lst для этого ребенка.

Как только вы подключите уровень i + 1, вы можете перейти на следующий уровень. Если после обхода уровня lst по-прежнему null, это означает, что ни один узел на этом уровне не имел потомка => это был последний уровень, алгоритм можно остановить.

Легко показать, почему это работает, это занимает линейное время и постоянное пространство, так что это строго лучше, чем BFS с очередью (которая требует линейной памяти).

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

  • 2

    Следуя идее Ишамаэля, я бы предложил процедуру, аналогичную

    void link_levels(Tree* t){
        Tree *head, *tail, *end_of_row;
        assert (t != 0);
        t->next = 0;
        head = tail = end_of_row = t;
        while(head != 0){
            if(head->left != 0){
                tail->next = head->left;
                tail = tail->next;
                tail->next = 0;
            }
            if(head->right != 0){
                tail->next = head->right;
                tail = tail->next;
                tail->next = 0;
            }
            if(head == end_of_row){
                head = head->next;
                end_of_row->next = 0;
                end_of_row = tail;
            }
            else {
                head = head->next;
            }
        }
    }
    
    17.01.2017

    3

    Используйте BFS, как предложено в комментариях. Тогда у вас будет расстояние каждого узла от корня.

    псевдокод:

     vis[1..n] = false   // mark each node as un-visited
     dis[1..n] = 0
     Queue q
     dis[root] = 0 
     vis[root] = true
     q.push(root)
     while !q.empty()
         node x = q.front()
         children[] = children nodes of node x
         for each child in children 
              !vis[child] 
                dis[child] = dis[x] + 1 
                vis[child] =true 
                q.enqueue(child)
         q.pop()
    

    Теперь у вас будет расстояние каждого узла от корня, агрегирование каждого узла на основе расстояния и возможность соединения узлов в соответствии с вашими требованиями.

    17.01.2017
  • Узлы могут быть связаны друг с другом в одном цикле, потому что они появятся в очереди в порядке 0 1 2 3 4 5 6 7 9. 17.01.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..