Как преобразовать двоичное дерево бинарного дерева поиска на месте, то есть, мы не можем использовать любое дополнительное пространство

голоса
12

Как преобразовать двоичное дерево бинарное дерево поиска на месте, то есть, мы не можем использовать любое дополнительное пространство.

Задан 05/04/2010 в 06:46
источник пользователем
На других языках...                            


10 ответов

голоса
0

Двоичное дерево обычно это бинарное дерево, в этом случае не требуется никакого преобразования.

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

Ответил 05/04/2010 в 07:00
источник пользователем

голоса
0

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

Это ужасный алгоритм многоборье - O (N ^ 2) время работы с неподходящим выходом бинарного дерева, но это достойная отправной точкой, прежде чем придумать что-то лучше и имеет то преимущество, что вы можете быть в состоянии написать код это примерно 20 линий на доске.

Ответил 05/04/2010 в 07:50
источник пользователем

голоса
10

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

Я предполагаю, что узлы дерева выглядят

struct tree_node {
    struct tree_node * left;
    struct tree_node * right;
    data_t data;
};

Я также предполагаю, что вы можете прочитать C

В то время как мы могли бы просто сидеть интересно, почему это дерево было когда-либо создано, не будучи создан в отсортированном порядке, что не делает нам никакой пользы, так что я буду игнорировать это и просто иметь дело с его сортировку.

Требование, чтобы не использовать никакого дополнительное пространство нечетное. Временно будет дополнительное пространство, если только в стеке. Я буду считать, что это означает, что вызов таНос или что-то подобное, а также, что в результате дерево имеет использовать не больше памяти, чем оригинальное несортированным дерево.

Первое и самый простое решением является сделать обход в неотсортированном дереве извлекая каждый узел из этого дерева и делают отсортированные вставки в новое дерево. Это O (п + п войти (п)), который представляет собой О (п log (п)).

Если это не то, что они хотят, и вы будете иметь, чтобы использовать ротацию и прочее ..... это ужасно!

Я думал, что вы могли бы сделать это, делая нечетную версию кучи сортировки, но я столкнулся с проблемами. Другое дело, что пришел в голову, что было бы ужасно медленно, будет делать нечетное версию пузырьковой сортировки на дереве.

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

Я уверен, что либо это считался новым алгоритм кем-то еще до меня, и имеет крутое название, что я просто не знаю, или что существенные недостатки в некотором роде, что я не вижу.

Далее с расчетами во время выполнения для второго предложения является довольно сложным. Сначала я подумал, что было бы просто O (N ^ 2), как пузырь и шейкер сорта, но я не могу удовлетворить себя, что избегание поддерева обхода может не выиграть достаточно, чтобы сделать его немного лучше, чем O (N ^ 2). По существу пузыря и шейкер сортирует эту оптимизацию тоже, но только на концах, где общее sortedness происходит рано, и вы можете срубить пределы. С помощью этого дерева версии вы получаете oppurtunities, чтобы возможно избежать кусков в середине сета, а также. Ну, как я уже сказал, это, вероятно, смертельно недостатки.

Ответил 05/04/2010 в 08:09
источник пользователем

голоса
-1

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

Ответил 15/12/2010 в 05:12
источник пользователем

голоса
1

Есть следующий алгоритм, чтобы достичь решения.

1) найти в порядке правопреемника без использования пространства.

Node InOrderSuccessor(Node node)
{ 
    if (node.right() != null) 
    { 
        node = node.right() 
        while (node.left() != null)  
            node = node.left() 
        return node 
    }
    else
    { 
        parent = node.getParent(); 
        while (parent != null && parent.right() == node)
       { 
            node = parent 
            parent = node.getParent() 
        } 
        return parent 
    } 
} 

2) Есть ли в порядке обхода без использования пространства.

а) Найдите первый узел заказовМои обхода. Он должен оставил большинство ребенка дерева, если он имеет, или слева от первого правого ребенка, если у него есть, или право ребенок сам. б) Использование выше алгоритма для выяснения inoder преемника первого узла. с) Повторите шаг 2 для всех возвращенной преемники.

Использование выше 2 алгоритма и сделать в порядке обхода на бинарном дереве без использования дополнительного пространства. Сформировать дерево двоичного поиска при выполнении обхода. Но сложность в O(N2)худшем случае.

Ответил 15/12/2010 в 05:35
источник пользователем

голоса
-1

куча сортировать дерево .. NlogN сложности ..

Ответил 13/06/2011 в 20:23
источник пользователем

голоса
2

Сделайте PostOrder Traversal и от создания двоичного дерева поиска.

struct Node * newroot = '\0';

struct Node* PostOrder(Struct Node* root)
{
      if(root != '\0')
      {
          PostOrder(root->left);
          PostOrder(root->right);
          insertBST(root, &newroot);
      }
}

insertBST(struct Node* node, struct Node** root)
{
   struct Node * temp, *temp1;
   if( root == '\0')
   {
      *root == node;
       node->left ==  '\0';
       node->right == '\0';
   }
   else
   {
       temp = *root;
       while( temp != '\0')
       {
           temp1= temp;
           if( temp->data > node->data)
               temp = temp->left;
           else
               temp = temp->right;
       }
       if(temp1->data > node->data)
       {
           temp1->left = node;
       }
       else
       {
           temp1->right = node;
       }
       node->left = node->right = '\0';
    }
}
Ответил 10/01/2012 в 05:27
источник пользователем

голоса
14

Преобразование двоичного дерева в двусвязном list- можно сделать Inplace в O (N)
Тогда разбирайтесь с помощью сортировки слияния, NlogN
Преобразовать список обратно в дерево - O (п)

Простой NlogN решение.

Ответил 29/08/2012 в 15:37
источник пользователем

голоса
0
#include <stdio.h>
#include <stdlib.h>

typedef int data_t;

struct tree_node {
    struct tree_node * left;
    struct tree_node * right;
    data_t data;
};

        /* a bonsai-tree for testing */
struct tree_node nodes[10] =
{{ nodes+1, nodes+2, 1}
,{ nodes+3, nodes+4, 2}
,{ nodes+5, nodes+6, 3}
,{ nodes+7, nodes+8, 4}
,{ nodes+9, NULL, 5}
,{ NULL, NULL, 6}
,{ NULL, NULL, 7}
,{ NULL, NULL, 8}
,{ NULL, NULL, 9}
        };

struct tree_node * harvest(struct tree_node **hnd)
{
struct tree_node *ret;

while (ret = *hnd) {
        if (!ret->left && !ret->right) {
                *hnd = NULL;
                return ret;
                }
        if (!ret->left ) {
                *hnd = ret->right;
                ret->right = NULL;;
                return ret;
                }
        if (!ret->right) {
                *hnd = ret->left;
                ret->left = NULL;;
                return ret;
                }
        hnd = (rand() &1) ? &ret->left : &ret->right;
        }

return NULL;
}

void insert(struct tree_node **hnd, struct tree_node *this)
{
struct tree_node *ret;

while ((ret= *hnd)) {
        hnd = (this->data  < ret->data ) ? &ret->left : &ret->right;
        }
*hnd = this;
}

void show(struct tree_node *ptr, int indent)
{
if (!ptr) { printf("Null\n"); return; }

printf("Node(%d):\n", ptr->data);
printf("%*c=", indent, 'L');  show (ptr->left, indent+2);
printf("%*c=", indent, 'R');  show (ptr->right, indent+2);
}

int main(void)
{
struct tree_node *root, *this, *new=NULL;

for (root = &nodes[0]; this = harvest (&root);  ) {
        insert (&new, this);
        }

show (new, 0);
return 0;
}
Ответил 24/12/2012 в 00:49
источник пользователем

голоса
0
struct Node
{
    int value;
    Node* left;
    Node* right;
};

void swap(int& l, int& r)
{
    int t = l;
    l = r;
    r = t;
}

void ConvertToBST(Node* n, Node** max)
{
    if (!n) return;

    // leaf node
    if (!n->left && !n->right)
    {
        *max = n;
        return;
    }

    Node *lmax = NULL, *rmax = NULL;
    ConvertToBST(n->left, &lmax);
    ConvertToBST(n->right, &rmax);

    bool swapped = false;
    if (lmax && n->value < lmax->value)
    {
        swap(n->value, lmax->value);
        swapped = true;
    }

    if (rmax && n->value > rmax->value)
    {
        swap(n->value, n->right->value);
        swapped = true;
    }

    *max = n;
    if (rmax && rmax->value > n->value) *max = rmax;

    // If either the left subtree or the right subtree has changed, convert the tree to BST again
    if (swapped) ConvertToBST(n, max);
}
Ответил 14/09/2013 в 07:56
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more