Добавление элемента в сбалансированное бинарное дерево.
От: Ravshan  
Дата: 30.04.07 12:49
Оценка:
Как добавить с помощью функции Add(int) элемент в дерево, чтобы оно было сбалансированным? Сначала делал с помощью флажка f — поочередно налево, потом направо добавлялось. Но потом понял что при кол-ве элементов большим 7 неправильно работает.

class Element {
public:
int data;
Element* left;
Element* right;
Element();
Element(int);
};

void Tree::Add(int a) {
  if(root == NULL) {
   root = new Element(a);
      return;
  }
  AddElement(root, a);
}
void Tree::AddElement(Element* p, int a) {
if (p->left == NULL) {
 p->left = new Element(a);
 return;
}
if (p->right == NULL) {
 p->right = new Element(a);
 return;
}
if (f) {
 f=0;
 AddElement(p->right, a);
} else {
 f=1;
 AddElement(p->left, a);
}
}
Re: Добавление элемента в сбалансированное бинарное дерево.
От: Risk Server  
Дата: 30.04.07 13:14
Оценка:
Здравствуйте, Ravshan, Вы писали:

R>Как добавить с помощью функции Add(int) элемент в дерево, чтобы оно было сбалансированным? Сначала делал с помощью флажка f — поочередно налево, потом направо добавлялось. Но потом понял что при кол-ве элементов большим 7 неправильно работает.


Ну там всё не так просто, вернее всё просто не так.
Есть много способов строить сбалансированное дерево.
Один из них — АVL tree. Посмотреть как оно балансируется можно тут
Re[2]: Добавление элемента в сбалансированное бинарное дерев
От: Аноним  
Дата: 30.04.07 21:46
Оценка:
Здравствуйте, Risk Server, Вы писали:

RS>Здравствуйте, Ravshan, Вы писали:


R>>Как добавить с помощью функции Add(int) элемент в дерево, чтобы оно было сбалансированным? Сначала делал с помощью флажка f — поочередно налево, потом направо добавлялось. Но потом понял что при кол-ве элементов большим 7 неправильно работает.


RS>Ну там всё не так просто, вернее всё просто не так.

RS>Есть много способов строить сбалансированное дерево.
RS>Один из них — АVL tree. Посмотреть как оно балансируется можно тут

Дело в том, что у него не поисковое дерево.
Re[3]: Добавление элемента в сбалансированное бинарное дерев
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 01.05.07 05:35
Оценка:
Здравствуйте, <Аноним>, Вы писали:

RS>>Ну там всё не так просто, вернее всё просто не так.

RS>>Есть много способов строить сбалансированное дерево.
RS>>Один из них — АVL tree. Посмотреть как оно балансируется можно тут

А>Дело в том, что у него не поисковое дерево.


Очень даже поисковое! Смотри внимательно.
... << RSDN@Home 1.2.0 alpha rev. 672>>
Re[4]: Добавление элемента в сбалансированное бинарное дерев
От: _DAle_ Беларусь  
Дата: 01.05.07 14:55
Оценка:
Здравствуйте, konsoletyper, Вы писали:

K>Здравствуйте, <Аноним>, Вы писали:


RS>>>Ну там всё не так просто, вернее всё просто не так.

RS>>>Есть много способов строить сбалансированное дерево.
RS>>>Один из них — АVL tree. Посмотреть как оно балансируется можно тут

А>>Дело в том, что у него не поисковое дерево.


K>Очень даже поисковое! Смотри внимательно.


А можно все-таки пояснить, что в том дереве поискового?
Re[5]: Добавление элемента в сбалансированное бинарное дерев
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 01.05.07 15:29
Оценка:
Здравствуйте, _DAle_, Вы писали:

_DA>А можно все-таки пояснить, что в том дереве поискового?


Да, кажется я ошибся, посыпаю голову пеплом . Поглядел невниметельно . Только вот вопрос: а нафига вообще нужно такое дерево? Каким критериям оно должно удовлетворять? Если никаких ограничений не накладыватеся, то алгоритм добавления такой, чтобы дерево сохраняло сбалансированность, тривиален.
... << RSDN@Home 1.2.0 alpha rev. 672>>
Re: Добавление элемента в сбалансированное бинарное дерево.
От: Кодт Россия  
Дата: 03.05.07 10:26
Оценка:
Здравствуйте, Ravshan, Вы писали:

R>Как добавить с помощью функции Add(int) элемент в дерево, чтобы оно было сбалансированным? Сначала делал с помощью флажка f — поочередно налево, потом направо добавлялось. Но потом понял что при кол-ве элементов большим 7 неправильно работает.


Представь себе двоичную кучу — дерево, отображённое на линейный массив послойно.
Т.е.
a1 — корень
a2,a3 — дети корня
a4...a8 — дети a2 и a3
и т.д.
(здесь удобна нумерация с единицы).

Даже в наивном исполнении, когда a_k -> a_2k,a_(2k+1), дисбаланс по высоте не превосходит 1.

Хотя по количеству — увы, может достигать 2^(h-1), где h — высота. Это в абсолютных значениях, а в относительных — всего лишь примерно 4:3.

Попробуем устранить и эту несправедливость.
Пусть полностью уравновешенное дерево имеет высоту h, и соответственно, (2^h)-1 элементов.
Начнём заполнять новый слой.
0-й (начинаем новый отсчёт с нуля, для удобства) — налево,
1-й направо
2-й налево
3-й направо

Казалось бы!
Но ведь баланс дерева означает и баланс поддеревьев. Поэтому уточним
0-й налево налево
1-й налево направо
2-й направо налево
3-й направо направо

Ага! На каждом шаге решение зависит от очередного бита, начиная с младшего!

Теперь можем забыть про массив, тем более, что в таком виде последний слой оказывается разреженным. Возвращаемся к дереву.
struct Node;
typedef Node* NodePtr; // или умный указатель - дело хозяйское

struct Node
{
    NodePtr left, right;
    Data data;
};

struct Tree
{
    NodePtr root;
    int size;

    void add(NodePtr newnode)
    {
        ++size;
        add_impl(root, size, newnode);
    }
    
    void add_impl(NodePtr& node, int index, NodePtr newnode)
    {
        if(!node)
        {
            assert(index == 1); // 0 - для самого первого узла, 1 - для всех остальных
            node = newnode;
        }
        else
            add_impl((index%2)==0 ? node->left : node->right, (index/2), newnode);
    }
    
    // можно концевую рекурсию заменить итерациями
    void add(NodePtr newnode)
    {
        NodePtr* pnode = &root;
        int index = ++size;
        while(index != 1)
        {
            pnode = &((index%2)==0 ? (*pnode)->left : (*pnode)->right);
            index /= 2;
        }
        *pnode = newnode;
    }
};

Вот, если ничего в мелочах не напутал, то должно работать.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[2]: Добавление элемента в сбалансированное бинарное дерев
От: Ravshan  
Дата: 09.05.07 13:20
Оценка:
Спасибо огроменное!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.