Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Вероника99
4 / 4 / 1
Регистрация: 16.12.2013
Сообщений: 420
#1

Поиск в двоичном дереве - C++

22.06.2016, 17:00. Просмотров 165. Ответов 2
Метки нет (Все метки)

Добрый день. Нужно построить англо-русский словарь как двоичное дерево. Каждая компонента содержит английское слово, соответствующее ему русское слово и счетчик количества обращений к данной компоненте. Дальше нужно сформировать новое представление словаря в виде двоичного дерева по следующему алгоритму:
а) в старом словаре ищется компонента с наибольшим значением
счетчика обращений;
б) найденная компонента заносится в новый
словарь и удаляется из старого;
в) переход к п. а) до исчерпания исходного словаря;
Пока что есть добавление узлов в дерево, возникли проблемы с поиском максимального счетчика и вывода дерева.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <iostream>
#include <string>
using namespace std;
 
string temp_eng;
string temp_rus;
int temp_count;
int lev=0;
struct tree
{
    string eng; //слово
    string rus; //слово
    int count; //количество обращений
    tree *left;
    tree *right;
};
// Функция создания первого элемента
// Функция фoрмирования первого элемента дерева:
tree *first (string temp_eng,string temp_rus,int temp_count)
{
    tree *pv=new tree;
    pv->eng=temp_eng;
    pv->rus=temp_rus;
    pv->count=temp_count;
    pv->left=0;
    pv->right=0;
    return pv;
}
 
// Функция поиска и добавления элемента в дерево:
tree *search_insert (tree *root, string temp_eng, string temp_rus,int temp_count)
{
    tree *pv=root, *prev;
    bool found=false;
    //поиск по дереву
    while (pv&&!found) 
    {
    prev=pv;
    if ((temp_eng==pv->eng)&&(temp_rus==pv->rus))
        found = true;
    else if (temp_count < pv->count)
        pv=pv->left;
    else pv=pv->right;
    }
    if (found) return pv;
    //создание нового узла
    tree *pnew=new tree;
    pnew->eng=temp_eng;
    pnew->eng=temp_rus;
    pnew->count=temp_count;
    pnew->left=0;
    pnew->right=0;
    if (temp_count < prev->count)
    prev->left=pnew; //присоединение к левому поддереву предка
    else prev->right=pnew; //присоединение к правому поддереву предка
    return pnew;
}
//функция поиска наибольшего счетчика
void seek_count (tree *root) //ПРОБЛЕМА ЗДЕСЬ
{
    tree *p=root;
    int max_l=0;
    while(p!=NULL)
    {
        if(max_l<p->count)
        {
            max_l=p->count;
        }
        else
            p=p->left; //еще нужен обход по правому узлу
 
    }
    cout<<"\n"<<max_l<<endl;
}
// Функция показа дерева
void print_tree (tree *p, int level) //И здесь проблема
{
    if (p)
    {
        print_tree(p->left, level+1);
        for (int i=0; i<level; i++)
        cout<<" ";
        cout<<p->eng<<endl;
            cout<<p->rus<<endl;
        for (int i=0; i<level; i++)
        cout<<" ";
        cout<<p->count<<endl;
        print_tree (p->right, level+1);
    }
    lev=level;
}
int main()
{
    tree *root=NULL;
    for(int i=0;i<2;i++)
    {
    cout<<"Vvedite angliskoe slovo: "<<endl;
    cin>>temp_eng;
        cout<<"Vvedite russkoe slovo: "<<endl;
    cin>>temp_rus;
    cout<<"Vvedite znachenie schetchika: "<<endl;
    cin>>temp_count;
    if(!root)
    {
        root=first(temp_eng,temp_rus,temp_count);
    }
    else 
        root=search_insert (root, temp_eng, temp_rus,temp_count);
    }
    print_tree (root, 0);
    seek_count(root);
    return 0;
}
Подскажите пожалуйста,как правильно перебираться все узлы дерева,чтобы найти в нем максимальный счетчик?Я запуталась немного
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.06.2016, 17:00     Поиск в двоичном дереве
Посмотрите здесь:

Представление выражения в двоичном дереве C++
C++ Поиск в двоичном файле
Поиск в Бинарном Дереве! C++
C++ Подсчет уровней в двоичном дереве поиска
C++ В двоичном дереве удалить все узлы, значения которых является простым числом
Как найти в двоичном дереве поиска минимальный элемент, превышающий некоторое заданное значение? C++
C++ Как найти в двоичном дереве поиска минимальный элемент, превышающий некоторое заданное значение?
Поиск листьев в дереве C++
Поиск дубликатов в бинарном дереве C++
C++ Реализация словаря в двоичном дереве поиска
Реализация словаря в двоичном дереве поиска C++
Поиск минимальной суммы в дереве C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
stzer
86 / 62 / 17
Регистрация: 26.10.2013
Сообщений: 190
Завершенные тесты: 2
22.06.2016, 18:31     Поиск в двоичном дереве #2
Можно воспользоваться обходом в ширину.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
size_t seek_count (tree *root)
{
    assert(root != nullptr);
    
    size_t max = root->count;
    std::queue<tree *> nodes;
    nodes.push(root);
    while (nodes.size() != 0)
    {
        auto temp = nodes.front();
        
        if (temp->count > max)
            max = temp->count;
        
        if (temp->left)
            nodes.push(temp->left);
        
        if (temp->right)
            nodes.push(temp->right);
        
        nodes.pop();
    }
    return max;
}
Вроде так =)
Вероника99
4 / 4 / 1
Регистрация: 16.12.2013
Сообщений: 420
22.06.2016, 19:53  [ТС]     Поиск в двоичном дереве #3
Тут разобралась, сделала таким образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
int max_l=0;
tree *seek_count (tree *p, int level)
{
    if(p)
    {
        if(max_l<p->count)
        {
            max_l=p->count;
            
        }
        seek_count(p->left,level+1);
            seek_count(p->right,level+1);
 
    }
    return p;
}
 
void print_tree (tree *p, int level)
{
    if (p)
    {
        print_tree(p->left, level+1);
        for (int i=0; i<level; i++)
        cout<<" ";
        cout<<p->eng<<endl;
            cout<<p->rus<<endl;
        for (int i=0; i<level; i++)
        cout<<" ";
        cout<<p->count<<endl;
        print_tree (p->right, level+1);
    }
    lev=level;
}
Теперь думаю,как организовать пункт б: найденная компонента заносится в новый словарь и удаляется из старого;
Пока есть такое:
C++
1
2
3
4
5
6
7
8
...
tree *p=seek_count(root,0); //р-найденный узел с максимальным счетчиком
    DeleteNode(p); // передаю в функцию удаления узла найденное значение
    cout<<"\nMax= "<<max_l<<endl;
    tree *new_root=NULL;
    if(new_root==NULL)
        new_root=copy_root(p); //заношу в новый словарь найденное значение
    print_tree (new_root, 0);
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tree* copy_root(tree*p)
{
 
    tree *pv=new tree;
    pv->eng=p->eng;
    pv->rus=p->rus;
    pv->count=p->count;
    pv->left=0;
    pv->right=0;
    return pv;
}
tree* DeleteNode(tree*p) //как правильно удалить найденный узел
{
    if(p==NULL)
        return;
 
}
Как правильно удалить найденный узел,подскажите пожалуйста?

Добавлено через 54 минуты
Вообщем написала такую функцию удаления,почему оно не удаляет узел?вроде все по правилам делала
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void DeleteNode(tree*root,tree*p)
{
    tree *p_new,*pp;
    if(p->left==NULL&&p->right==NULL)
    {
        p=NULL;
        return;
    }
    else if(p->right==NULL)
    {
        p=p->left;
        return;
    }
    else if(p->left==NULL)
    {   p=p->right;
    return;
    }
    else
    {
        p_new=p->left;
        pp=p;
        while(p_new->right!=NULL)
        {
            pp=p_new;
            p_new=p_new->right;
        }
        p_new->right=p->right;
        if(pp!=p)
        {
            pp->right=p_new->left;
            p_new->left=p->left;
        }
    }
    p=p_new;
    
    free(p);
    return;
}
C++
1
2
3
4
tree *p=seek_count(root,0);
    cout<<"Delete"<<endl;
    DeleteNode(root,p);
        print_tree (root, 0);
Yandex
Объявления
22.06.2016, 19:53     Поиск в двоичном дереве
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru