Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Алгоритм вставки и удаления в АВЛ дерево

5.8K
24 мая 2004 года
Digi
15 / / 25.03.2004
Народ, кто нибудь может добыть сабж, желательно на C, или подробное объяснение алгоритма??? Очень надо. Всем кто поможет, заранее большое спасибо!
272
24 мая 2004 года
vladsoft
512 / / 20.08.2000
Цитата:
Originally posted by Digi
Народ, кто нибудь может добыть сабж, желательно на C, или подробное объяснение алгоритма??? Очень надо. Всем кто поможет, заранее большое спасибо!


А что это за покимон и как его едят...

5.8K
25 мая 2004 года
Digi
15 / / 25.03.2004
Цитата:
Originally posted by vladsoft

А что это за покимон и как его едят...



АВЛ - дерево, это дерево, в котром высота левого поддерва равна высоте правого поддерева или отличается на 1.

Вот пример АВЛ - дерева для ряда чисел {1,2,3,4,5}

 
Код:
2
                   / \
                  1   4                  
                     / \
                    3   5


А вот пример обычного двоичного дерева поиска, для ряда чисел {1,2,3,4,5}:
 
Код:
1
                           \
                            2
                             \
                              3
                               \
                                4
                                 \
                                  5


Чувствуется разница????
272
25 мая 2004 года
vladsoft
512 / / 20.08.2000
Цитата:
Originally posted by Digi


АВЛ - дерево, это дерево, в котром высота левого поддерва равна высоте правого поддерева или отличается на 1.

Вот пример АВЛ - дерева для ряда чисел {1,2,3,4,5}
 
Код:
2
                   / \
                  1   4                  
                     / \
                    3   5


А вот пример обычного двоичного дерева поиска, для ряда чисел {1,2,3,4,5}:
 
Код:
1
                           \
                            2
                             \
                              3
                               \
                                4
                                 \
                                  5


Чувствуется разница????


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

272
25 мая 2004 года
vladsoft
512 / / 20.08.2000
Цитата:
Originally posted by vladsoft

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


Посмотри в архиве, там что-то есть...

5.8K
25 мая 2004 года
Digi
15 / / 25.03.2004
Цитата:
Originally posted by vladsoft

Посмотри в архиве, там что-то есть...



К сожалению не нашел в исходниках того, что было надо. Но все равно, огромное спасибо за проявленный интерес. Буду искать дальше. Если, все-таки, сделаю эти деревья и если интересно, то потом могу выслать исходники :) .

272
25 мая 2004 года
vladsoft
512 / / 20.08.2000
Цитата:
Originally posted by Digi


К сожалению не нашел в исходниках того, что было надо. Но все равно, огромное спасибо за проявленный интерес. Буду искать дальше. Если, все-таки, сделаю эти деревья и если интересно, то потом могу выслать исходники :) .


там есть принцип работы с двоичными древьями...от него и отталкивайся...Если ято-то получится то пиши...

5.8K
26 мая 2004 года
Digi
15 / / 25.03.2004
Цитата:
Originally posted by vladsoft

там есть принцип работы с двоичными древьями...от него и отталкивайся...Если ято-то получится то пиши...



Да принцип работы обычного двоичного дерева поиска я себе хорошо представляю :). В нем то как раз и нет ничего сложного. Вот с АВЛ... там проблемы. Но я уже нашел кое-какую инфу, где достаточно понятно описаны АВЛ деревья. Щас отлаживаю вставку. Думаю завтра уже буду делать удаление.
Как сделаю, то сразу расскажу как и что, если интересно, ну или исходники приаттачу. :)

272
26 мая 2004 года
vladsoft
512 / / 20.08.2000
Цитата:
Originally posted by Digi


Да принцип работы обычного двоичного дерева поиска я себе хорошо представляю :). В нем то как раз и нет ничего сложного. Вот с АВЛ... там проблемы. Но я уже нашел кое-какую инфу, где достаточно понятно описаны АВЛ деревья. Щас отлаживаю вставку. Думаю завтра уже буду делать удаление.
Как сделаю, то сразу расскажу как и что, если интересно, ну или исходники приаттачу. :)


Хорошо давай, если что пиши вместе обмазгуем...

460
26 мая 2004 года
Berg
261 / / 27.03.2003
Цитата:
Originally posted by Digi
Народ, кто нибудь может добыть сабж, желательно на C, или подробное объяснение алгоритма??? Очень надо. Всем кто поможет, заранее большое спасибо!



http://algolist.manual.ru/
(Структуры данных\AVL-деревья)

А вот тут http://www.geocities.com/wkaras/gen_cpp/avl_tree.html с исходниками

5.8K
26 мая 2004 года
Digi
15 / / 25.03.2004
Цитата:
Originally posted by Berg


http://algolist.manual.ru/
(Структуры данных\AVL-деревья)

А вот тут http://www.geocities.com/wkaras/gen_cpp/avl_tree.html с исходниками



Спасибо большое :). Но писать буду все равно сам, т.к. уже половину сделал :). Но вторая ссылка думаю все равно будет очень полезна.

57K
31 января 2010 года
Remy-martin
3 / / 31.01.2010
Вторая ссылка не открывается((( может кто нить перезалить, или дать норм ссылку?
386
31 января 2010 года
newcss
297 / / 05.04.2005
Как я понимаю ты ищешь алгоритм работы со сбалансированными бинарными деревьями.
Алгоритм такой:
1) Добавляешь элемент в дерево
2) Проверяешь длину ветвей
3) Если длины отличаются более чем на 1, проводишь балансировку

Балансировка:
Балансировка проводится путем поворота (левого,правого, большого, малого).

Длину веток удобно искать при помощи стека (фифо) или очереди(лифо), что больше нравится

Есть методичка очень хорошая, составляли ее Матьяш и Ключарев.
http://window.edu.ru/window/library?p_rid=44820 там эти вопросы рассмотрены
57K
01 февраля 2010 года
Remy-martin
3 / / 31.01.2010
в общем то да, но может у кого есть исходники, желательно на с++? я программист начинающий, а тут задали блин: АВЛ-дерево, реализация поиска, вставки, удаления
5
01 февраля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Remy-martin
в общем то да, но может у кого есть исходники, желательно на с++? я программист начинающий, а тут задали блин: АВЛ-дерево, реализация поиска, вставки, удаления


Вы похоже читать тоже не умеете.

57K
01 февраля 2010 года
Remy-martin
3 / / 31.01.2010
благодарю за вашу иронию)) алгоритм я и до этого знал, на бумаге все решаю и расписываю, а прога не получается , мне нужны примеры как все это реализовать..
5
01 февраля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: Remy-martin
благодарю за вашу иронию)) алгоритм я и до этого знал, на бумаге все решаю и расписываю, а прога не получается , мне нужны примеры как все это реализовать..


У Вирта было хорошо написано (Алгоритмы и структуры данных) с примерами, на Модуле-2, правда. Вот статья на РСДН. Поиск рулит. :cool:

386
01 февраля 2010 года
newcss
297 / / 05.04.2005
Лабораторки за тебя здесь ни кто писать не будет.
Нужна реализация...
Код:
class B_tree
{
        public:
                B_tree ();                             //Конструктор "пустого" B-дерева
                B_tree (int amount, ...);       //Конструктор B-дерева, состоящего из amount элементов
                B_tree (const B_tree& b_tree);    //Конструктор копирования
                ~B_tree ();                          //Деструктор B-дерева
                void Add (int key);               //Добавление ключа key в структуру B-дерева
                bool Search (int key);          //Поиск ключа в B-дереве (true - найден, false - не найден)
                void Delete (int key);          //Удаление всех экземпляров ключа key в B-дереве, при отсутствии данного ключа структура остается без изменений
                void Print ();                       //Обход и вывод B-дерева на печать способом, используемым при составлении оглавления книг
       
        private:
                struct Page
                {
                        int RAmount;            //Фактическое число элементов на странице
                        Page *p0;               //Указатель на самого левого потомка страницы
                        struct Item
                        {
                                int key;           //Значение одного ключа страницы
                                Page *p;        //Указатель на страницу-потомок
                                int count;        //Число экземпляров данного ключа, хранимых на странице
                        } key_pt[4];           //Массив, хранящий значения ключей страницы и указатели на потомков страницы
                } *root;                         //Указатель на корень B-дерева
                void search_add_key (int key, Page *a, bool& grow, Page::Item& v);
                                                //Рекурсивная функция, выполняющая добавление ключа key в структуру B-дерева; a - указатель на страницу, grow - "B-дерево стало выше", v - передаваемый вверх элемент
                void print_b_tree (Page *a, int level);
                                                //Рекурсивная фунцкия, выполняющая печать B-дерева с уровня level
                bool search_key (int key, Page *a);
                                                //Рекурсивная функция, выполняющая поиск ключа в B-дереве (true - ключ найден, false - не найден)
                void delete_key (int key, Page *a, bool& smallsize);
                                                //Рекурсивная функция, выполняющая удаление ключа key из структуры B-дерева, a - указатель на страницу, smallsize - "страница a мала", требуется слияние страниц
                void del (int R, Page *a, Page *q, bool& smallsize);
                                                //Рекурсивная функция, выполняющая балансировку B-дерева после удаления ключа key из его структуры, при необходимости производит слияние страниц
                void fusion (Page *father, Page *son, int R, bool& smallsize);
                                                //Функция, выполняющая слияние страниц B-дерева, father - "страница отец", son - "страница-сын отца", на которой число элементов меньше допустимого, R - индек удаляемого из страницы-отца элемента, smallsize - "страница-отец мала"
                void destroy (Page *a);            //"Деструктор" вершины a B-дерева
                void copy (Page *a, Page *b);    //Рекурсивная функция, создающая копию b страницы B-дерева a
};
B_tree::B_tree()
{
        root = NULL;
}
B_tree::B_tree (int amount, ...)
{
        short i = 0;
        root = NULL;
        va_list key_vl;
        va_start (key_vl, amount);
        while ((key_vl != NULL) && (++i <= amount))
                Add (va_arg (key_vl, int));
        va_end (key_vl);
}
B_tree::B_tree (const B_tree& b_tree)
{
        root = new Page;
        if (b_tree.root != NULL)
                copy (b_tree.root, root);
        else
            root = NULL;
}
void B_tree::copy (Page *a, Page *b)
{
        Page *p1, *p2, *p3, *p4, *p5;
        if (a != NULL)
        {
            b->RAmount = a->RAmount;
            for (int i=0; i < a->RAmount; i++)
            {
                    b->key_pt.key = a->key_pt.key;
                    b->key_pt.count = a->key_pt.count;
            }
            if ((a->RAmount >= 1) && (a->p0 != NULL))
            {
                    p1 = new Page;
                    p2 = new Page;
            }
            else
            {    
                    p1 = NULL;
                    p2 = NULL;
            }
            if ((a->RAmount >= 2) && (a->p0 != NULL))
                    p3 = new Page;
            else
                    p3 = NULL;
            if ((a->RAmount >= 3) && (a->p0 != NULL))
                    p4 = new Page;
            else
                    p4 = NULL;
            if ((a->RAmount == 4) && (a->p0 != NULL))
                    p5 = new Page;
            else
                    p5 = NULL;
            b->p0 = p1;
            b->key_pt[0].p = p2;
            b->key_pt[1].p = p3;
            b->key_pt[2].p = p4;
            b->key_pt[3].p = p5;
            if (a->RAmount >= 1)
            {
                    copy (a->p0, p1);
                    copy (a->key_pt[0].p, p2);
            }
            if (a->RAmount >= 2)
                    copy (a->key_pt[1].p, p3);
            if (a->RAmount == 3)
                    copy (a->key_pt[2].p, p4);
            if (a->RAmount == 4)
                    copy (a->key_pt[3].p, p5);
        }
}
B_tree::~B_tree()
{
        destroy (root);
        root = NULL;
}
void B_tree::destroy (Page *a)
{
        Page *p1, *p2, *p3, *p4, *p5;
        if (a != NULL)
        {
            if (a->RAmount >= 1)
            {
                    p1 = a->p0;
                    p2 = a->key_pt[0].p;
            }
            else
            {
                    p1 = NULL;
                    p2 = NULL;
            }
            if (a->RAmount >= 2)
                    p3 = a->key_pt[1].p;
            else
                    p3 = NULL;
            if (a->RAmount >= 3)
                    p4 = a->key_pt[2].p;
            else
                    p4 = NULL;
            if (a->RAmount == 4)
                 p5 = a->key_pt[3].p;
            else
                    p5 = NULL;
            delete a;
       
        destroy (p1);
        destroy (p2);
        destroy (p3);
        destroy (p4);
        destroy (p5);
        }
}
void B_tree::Add (int key)
{
        bool grow;
        Page::Item u;
        Page *bufer_root;
        search_add_key (key, root, grow, u);
        if (grow == true)
        {
                bufer_root = root;
                root = new Page;
                root->p0 = NULL;
                root->key_pt[0].p = NULL;
                root->key_pt[1].p = NULL;
                root->key_pt[2].p = NULL;
                root->key_pt[3].p = NULL;
                root->RAmount = 1;
                root->p0 = bufer_root;
                root->key_pt[0] = u;
        }
}
386
01 февраля 2010 года
newcss
297 / / 05.04.2005
Продолжение
Код:
void B_tree::search_add_key (int key, Page *a, bool& grow, Page::Item& v)
{
        short i, L, R;
        Page *b;
        Page::Item u;
       
        if (a == NULL)
        {
                grow = true;
                v.key = key;
                v.p = NULL;
                v.count = 1;
        }
        else
        {
                L = 0;
                R = a->RAmount;
                while (L < R)
                {
                        i = (L+R)/2;
                        if (a->key_pt.key <= key)
                                L = i+1;
                        else
                                R = i;
                }
                R = R-1;
                if ((R >= 0) && (a->key_pt[R].key == key))
                        a->key_pt[R].count++;
                else
                {
                        if (R == -1)
                                search_add_key (key, a->p0, grow, u);
                        else
                                search_add_key (key, a->key_pt[R].p, grow, u);
                        if (grow == true)
                        {
                                if (a->RAmount < 4)
                                {
                                        grow = false;
                                        a->RAmount++;
                                        for (i = a->RAmount-1; i >= R+2; i--)
                                                a->key_pt = a->key_pt[i-1];
                                        a->key_pt[R+1] = u;
                                }
                                else
                                {
                                        b = new Page;
                                        b->p0 = NULL;
                                        b->key_pt[0].p = NULL;
                                        b->key_pt[1].p = NULL;
                                        b->key_pt[2].p = NULL;
                                        b->key_pt[3].p = NULL;
                                        if (R <= 1)
                                        {
                                                if (R == 1)
                                                        v = u;
                                                else
                                                {
                                                        v = a->key_pt[1];
                                                        for (i=1; i>=R+1; i--)
                                                                a->key_pt = a->key_pt[i-1];
                                                        a->key_pt[R+1] = u;
                                                }
                                                for (i=0; i<=1; i++)
                                                        b->key_pt = a->key_pt[i+2];
                                        }
                                        else
                                        {
                                                R = R-2;
                                                v = a->key_pt[2];
                                                for (i=0; i<=R-1; i++)
                                                        b->key_pt = a->key_pt[i+3];
                                                b->key_pt[R] = u;
                                                for (i=R+1; i<=1; i++)
                                                        b->key_pt = a->key_pt[i+2];
                                        }
                                        a->RAmount = 2;
                                        b->RAmount = 2;
                                        b->p0 = v.p;
                                        v.p = b;
                                }
                        }
                }
        }
}
bool B_tree::Search (int key)
{
        return (search_key (key, root));
}
bool B_tree::search_key (int key, Page *a)
{
        short i, L, R;
   
        if (a == NULL)
                return (false);
        else
        {
                L = 0;
                R = a->RAmount;
                while (L < R)
                {
                        i = (L+R)/2;
                        if (a->key_pt.key <= key)
                                L = i+1;
                        else
                                R = i;
                }
                R = R-1;
                if ((R >= 0) && (a->key_pt[R].key == key))
                        return (true);
                else
                        if (R == -1)
                                search_key (key, a->p0);
                        else
                                search_key (key, a->key_pt[R].p);
        }                        
}
void B_tree::Delete (int key)
{        
        bool smallsize;
        Page *bufer_root;
        delete_key (key, root, smallsize);
        if (smallsize == true)
        {
                if (root->RAmount == 0)
                {
                        bufer_root = root;
                        root = bufer_root->p0;
                        delete bufer_root;
                }
        }
}
void B_tree::delete_key (int key, Page *a, bool& smallsize)
{
        short i, L, R;
        Page *q;
        if (a == NULL)
                smallsize = false;
        else
        {
                L = 0;
                R = a->RAmount;
                while (L < R)
                {
                        i = (L+R)/2;
                        if (a->key_pt.key < key)
                                L = i+1;
                        else
                                R = i;
                }
                if (R == 0)
                        q = a->p0;
                else
                        q = a->key_pt[R-1].p;
                if ((R <= a->RAmount-1) && (a->key_pt[R].key == key))  
                {
                        if (q == NULL)
                        {
                            a->RAmount--;
                            smallsize = (a->RAmount < 2);
                            for (i=R; i<a->RAmount; i++)
                                    a->key_pt = a->key_pt[i+1];
                        }
                        else
                        {
                                del(R, a, q, smallsize);
                                if (smallsize == true)
                                        fusion (a, q, R-1, smallsize);
                        }
                }
                else
                {
                        delete_key (key, q, smallsize);
                        if (smallsize == true)
                                fusion (a, q, R-1, smallsize);
                }
        }
}
void B_tree::del (int R, Page *a, Page *q, bool& smallsize)
{
        Page *b;
        b = q->key_pt[q->RAmount-1].p;
        if (b != NULL)
        {
                del (R, a, b, smallsize);
                if (smallsize == true)
                        fusion (q, b, q->RAmount-1, smallsize);
        }
        else
        {
            q->key_pt[q->RAmount-1].p = a->key_pt[R].p;
            a->key_pt[R] = q->key_pt[q->RAmount-1];
            q->RAmount--;
            smallsize = (q->RAmount < 2);
        }
}
386
01 февраля 2010 года
newcss
297 / / 05.04.2005
Код:
void B_tree::fusion (Page *father, Page *son, int R, bool& smallsize)
{
        Page *b;
        int i, k, RAb, RAfather;
        RAfather = father->RAmount;
        if (R < RAfather-1)
        {
                R++;
                b = father->key_pt[R].p;
                RAb = b->RAmount;
                k = (RAb-2+1)/2;
                son->key_pt[1] = father->key_pt[R];
                son->key_pt[1].p = b->p0;
                if (k > 0)
                {
                        for (i=0; i <= k-1; i++)
                                son->key_pt[i+2] = b->key_pt;
                        father->key_pt[R] = b->key_pt[k];
                        father->key_pt[R].p = b;
                        b->p0 = b->key_pt[k].p;
                        RAb = RAb-k-1;
                        for (i=0; i < RAb; i++)
                                b->key_pt = b->key_pt[i+k+1];
                        b->RAmount = RAb;
                        son->RAmount = 2-1+(k+1);
                        smallsize = false;
                }
                else    
                {
                        for (i=0; i < 2; i++)
                                son->key_pt[i+2] = b->key_pt;
                        for (i=R; i < RAfather-1; i++)
                                father->key_pt = father->key_pt[i+1];
                        son->RAmount = 4;
                        father->RAmount--;
                        smallsize = (father->RAmount < 2);
                        delete b;
                }
        }
        else
        {
                if (R == 0)
                        b = father->p0;
                else
                        b = father->key_pt[R-1].p;
                RAb = b->RAmount+1;
                k = (RAb-2)/2;
                if (k > 0)
                {
                        son->key_pt[k] = son->key_pt[0];
                        son->key_pt[k-1] = father->key_pt[R];
                        son->key_pt[k-1].p = son->p0;
                        RAb = RAb-k-1;
                        son->p0 = b->key_pt[RAb].p;
                        father->key_pt[R] = b->key_pt[RAb];
                        father->key_pt[R].p = son;
                        b->RAmount--;
                        son->RAmount = 2-1+k;
                        smallsize = false;
                }
                else    
                {
                    b->key_pt[RAb-1] = father->key_pt[R];
                    b->key_pt[RAb-1].p = son->p0;
                    b->key_pt[RAb] = son->key_pt[0];
                    b->RAmount = 4;
                    father->RAmount--;        
                    smallsize = (father->RAmount < 2);  
                    delete son;
                }
        }
}
void B_tree::Print ()
{
        print_b_tree (root, 0);        
}
void B_tree::print_b_tree (Page *a, int level)
{
        using namespace std;
        short i;
        if (a != NULL)
        {
                for (i=0; i<level; i++)
                        cout << "---";
                for (i=0; i<a->RAmount; i++)
                {
                        cout << a->key_pt.key; //<< "(" <<a->key_pt.count << ")";
                        if (i != a->RAmount-1)
                                cout << ", ";
                }
                cout << endl;
                print_b_tree (a->p0, level+1);
                for (i=0; i<a->RAmount; i++)
                        print_b_tree (a->key_pt.p, level+1);
        }
}


Правда это не бинарное дерево, а Б-дерево. Но организация и построение одно и тоже, посмотри, переделай. В свое время тож разбирался по этому исходнику...
http://forum.vingrad.ru/index.php?showtopic=71187 - Вот отсюда взят код, код рабочий, ну или почти, по крайней мере заставить работать мона.



P.S.> сори за так много сообщений, одним не влезло
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог