Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 1
Регистрация: 24.05.2015
Сообщений: 6
1

Удаление элементов из бинарного дерева (не дерево поиска)

24.05.2015, 23:28. Просмотров 850. Ответов 2
Метки нет (Все метки)

Задание заключается в создании бинарного дерева, из букв введенной строки, обходе дерева и удалении согласных букв из дерева.
проблема заключается в последнем задании. при удалении элемента все разделяется на 3 случая, как я понял нет потомков, 1 потомок, 2 потомка. поскольку у меня простое бинарное дерево, балансировать, вертеть его мне не требуется.
так вот ближе к сути, в моей реализации отсутствует указатель на предка, в результате чего удаление затруднено.
хотел реализовать рекурсивный алгоритм с обратным обходом для удаления элементов(чтоб указатели не потерять) но вываливается ошибка. по видимому изза NULL ов , точнее их отсутствия. попробовал прикрутить указатель на предка, но что то тоже не выходит.
подскажите алгоритм удаления по условию без использования указателя на предка или подскажите как при создании дополнить правильно это поле?

Добавлено через 1 минуту
заголовочный файл
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#pragma once
struct Node
{   char data;
    Node *left, *right, *parent;
 
};
class Tree
{
public:
    Node *CreateTree(int n, char*, Node*);
    void PrintTree(Node*,int n);
    Node *GetHead(){ return _head; }
    void PreOrderWalk(Node*);
    void DelСonsonants(Node*);
    Tree(int,char*);
    ~Tree();
private:
    Node *_head;
    int **Nodes;
    int _CountofNodes;
};
файл ресурсов
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
#include "Tree.h"
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
 
 
 
Tree::Tree(int n, char* s1)
{
    _head = CreateTree(n, s1, nullptr);
    _CountofNodes = n;
    Nodes = new int *[n];
    for (int i = 0; i < n; i++)
    {
        Nodes[i] = new int[n];
    }
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
    {
        Nodes[i][j] = 0;
    }
 
}
 
Node *Tree::CreateTree(int n, char* s1, Node *parent)
{
    int nl, nr;
    Node *head;
    if (n > 0 )
    {
        nl = n / 2;
        nr = n - nl - 1;
        head = new Node;
        head -> data = s1[rand()%20];
        head -> left = CreateTree(nl,s1,head);
        head->right = CreateTree(nr, s1,head);
        head->parent = parent;
    }
    else
    { 
        head = nullptr; 
    }
    return head;
}
 
void Tree::PrintTree(Node *head, int n)
{
    if ( head != nullptr)
    {
        PrintTree(head->right, n + 2);
        for (int i = 1; i < n; i++)
        {
            cout << "  ";
        }
        cout << head->data << endl;
        PrintTree(head->left, n + 2);
    }
}
 
void Tree::PreOrderWalk(Node *head)
{ 
    if (head == nullptr)    return;    //Если дерева нет, выходим
 
    cout << head->data << "  "; //Посетили узел
    PreOrderWalk(head->left); //Обошли левое поддерево    
    PreOrderWalk(head->right); //
}
 
void Tree::DelСonsonants(Node *head)
{   
    char Сonsonants[42] = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSVWXYZ";
        if (head == nullptr)    return;    //Если дерева нет, выходим;
        //DelСonsonants(head->left); //Обошли левое поддерево 
        //DelСonsonants(head->right); //Обошли правое поддерево  
        head->left;
        cout << endl << head->parent->data << endl;
        /*  for (int i = 0; i < 42; i++)
        {
            if (head->data == Сonsonants[i])
            {
            
            }
        }*/
}
Tree::~Tree()
{
}
файл основной программы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include "Tree.h"
using namespace std;
void main()
{
    const int n = 20;
    char s1[50];
    cout << "vvedite s " << endl;
    cin.getline(s1, n);
    Tree n1(n,s1);
    Node *head = n1.GetHead();
    n1.CreateTree(n,s1,nullptr);
    n1.PrintTree(head,n);
    system("pause");
    n1.PreOrderWalk(head);
    system("pause");
    n1.DelСonsonants(head);
    n1.PrintTree(head, n);
    system("pause");
 
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.05.2015, 23:28
Ответы с готовыми решениями:

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

Некорректное удаление элемента бинарного дерева поиска
Задача состоит в том, чтобы удалить максимальный в левом поддереве элемент и все его порожденные...

Удаление элемента из бинарного дерева поиска (bst)
Есть структура данных bst с методом delete (и некоторыми другими, не имеющими отношения к данной...

Удаление элемента из двоичного бинарного дерева поиска
Здравствуйте! Подскажите пожалуйста, как удалить элемент из двоичного бинарного дерева поиска,...

2
0 / 0 / 1
Регистрация: 24.05.2015
Сообщений: 6
29.05.2015, 03:00  [ТС] 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
#include <iostream>
#pragma once
struct Node
{   char data;
    Node *left, *right, *parent;
 
};
class Tree
{
public:
    Node *CreateTree(int n, char*, Node*);
    void PrintTree(Node*,int);
    Node *GetHead(){ return _head; }
    void PreOrderWalk(Node*);
    void DelСonsonants(Node*);
    Tree(int , char*);
    ~Tree();
private:
    Node *_head, *root = NULL;
    int **Nodes;
    int _CountofNodes;
    char s1[50];
};
ресурсы
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "Tree.h"
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
 
 
 
Tree::Tree(int n, char* s1)
{
    _CountofNodes = n;
    _head = CreateTree(n, s1, NULL);
    Nodes = new int *[n];
    for (int i = 0; i < n; i++)
    {
        Nodes[i] = new int[n];
    }
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
    {
        Nodes[i][j] = 0;
    }
 
}
Node *Tree::CreateTree(int n, char* s1, Node *parent)
{
    int nl, nr, l;
    Node *head;
    if (n > 0 )
    {
        nl = n / 2;
        nr = n - nl - 1;
        head = new Node;
        l = rand()%_CountofNodes;
        head -> data = s1[l];
        head->parent = parent;
        head -> left = CreateTree(nl,s1,head);
        head->right = CreateTree(nr, s1,head);
    }
    else
    { 
        head = nullptr; 
    }
    return head;
}
 
void Tree::PrintTree(Node *head, int n)
{
    if (n==0)
    int n = _CountofNodes;
    if ( head != NULL)
    {
        
        PrintTree(head->right,n+2);
        for (int i = 1; i < n; i++)
        {
            cout << "  ";
        }
        cout << head->data<< endl;
        PrintTree(head->left,n+2);
    }
    else return;
}
 
void Tree::PreOrderWalk(Node *head)
{ 
    if (head == NULL)    
    return;    //Если дерева нет, выходим
 
    cout << head->data << "  "; //Посетили узел
    PreOrderWalk(head->left); //Обошли левое поддерево    
    PreOrderWalk(head->right); //
}
 
void Tree::DelСonsonants(Node *head) 
{
    Node *p, *q;
    if (head == NULL) 
    return;
    DelСonsonants(head->left); //Обошли левое поддерево 
    DelСonsonants(head->right); //Обошли правое поддерево 
    char Сonsonants[42] = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSVWXYZ";
    for (int i = 0; i < 42; i++)
    { 
        if (head == NULL) break;
        if (head->data == Сonsonants[i])
        {
            if (head == _head)
            {
                if (head->left != NULL)
                {
                    Node *s = head->left;
                    head->data = s->data;
                    s->data='e';
                    break;
                }
                if (head->right!=NULL)
                {
                    Node *s = head->right;
                    head->data = s->data;
                    s->data = 'e';
                    break;
                }
                else 
                {
                    cout << "Дерево полностью состоит из согласных букв и было удалено";
                    return;
                }
            }
            if (head->left == NULL || head->right == NULL)
                q = head;
            else {
                q = head->right;
                while (q->left != NULL)
                    q = q->left;
            }
 
 
            if (q->left != NULL)
                p = q->left;
            else
                p = q->right;
 
            if (p != NULL)
                p->parent = q->parent;
 
            if (q->parent != NULL)
                if (q == q->parent->left)
                    q->parent->left = p;
                else
                    q->parent->right = p;
            else
                root = p;
 
            if (q != head) {
                q->left = head->left;
                if (q->left != NULL)
                    q->left->parent = q;
                q->right = head->right;
                if (q->right != NULL)
                    q->right->parent = q;
                q->parent = head->parent;
                if (head->parent != NULL)
                    if (head == head->parent->left)
                        head->parent->left = q;
                    else
                        head->parent->right = q;
                else
                    root = q;
                delete head;
                head = NULL;
                _CountofNodes--;
            }
            else
            {
                delete q;
                q = NULL;
                _CountofNodes--;
            }
        }
    }
}
Tree::~Tree()
{
}
основная
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
#include <iostream>
#include <iostream>
#include <fstream>
#include <clocale>
#include <string>
#include <cerrno>
#include "Tree.h"
using namespace std;
void AddFile(Node *head)
{   string str;
    ofstream fil(str);
    if (head == NULL)    return;    //Если дерева нет, выходим
    head->data = str[1];
    fil << str[1]  << "  "; //Посетили узел
    AddFile(head->left); //Обошли левое поддерево    
    AddFile(head->right); 
    fil.close();
}
 
void main()
{
    char s[20];
    setlocale(LC_CTYPE, "rus");
    for (int i = 0; i < 20; i++)
    {
        cin >> s[i];
    }
    
        Tree tr(20, s);
        tr.PrintTree(tr.GetHead(), 0);
        tr.PreOrderWalk(tr.GetHead());
        system("pause");
        cout << endl << endl << endl << endl;
        tr.DelСonsonants(tr.GetHead());
        tr.PrintTree(tr.GetHead(), 0);
        system("pause");
 
}
пойду меню делать а так интерфейс любой может прикрутить.
думаю, код кроме функции удаления читаем. а его придется принять как данность
0
_
317 / 151 / 27
Регистрация: 08.10.2011
Сообщений: 432
29.05.2015, 13:23 3
bodreevich, вот тебе вариант без поворотов, но со слиянием поддеревьев (поддеревья удаляемой вершины сливаем на месте в новое поддерево):
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
#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
 
const char CONSON[] = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
 
class BinTree {
private:
    struct Node {
        char c;
        Node *left;
        Node *right;
        Node(char cc, Node *ll = NULL, Node *rr = NULL) : c(cc), left(ll), right(rr) {}
    };
 
    Node *root;
 
    void buildTree(Node *&r, const char *str, int lo, int hi) {
        if (lo > hi) return;
        int mi = (hi + lo) / 2;
        r = new Node(str[mi]);
        buildTree(r->left, str, lo, mi - 1);
        buildTree(r->right, str, mi + 1, hi);
    }
 
    void printHelper(Node *r, int shift) {
        if (!r) return;
        printHelper(r->right, shift + 3);
        cout << setw(shift) << r->c << endl;
        printHelper(r->left, shift + 3);
    }
 
    void removeHelper(Node *&r) {
        if (!r) return;
        if (strchr(CONSON, r->c)) {
            Node *t = mergeLR(r->left, r->right);
            delete r;
            r = t;
            removeHelper(r);
        } else {
            removeHelper(r->left);
            removeHelper(r->right);
        }
    }
    
    Node *mergeLR(Node *lch, Node *rch) {
        if (!lch) return rch;
        if (!rch) return lch;
        if (rand() % 2) {
            lch->right = mergeLR(lch->right, rch);
            return lch;
        } else {
            rch->left = mergeLR(lch, rch->left);
            return rch;
        }
    }
 
public:
    BinTree(const char *str) {
        root = NULL;
        buildTree(root, str, 0, strlen(str) - 1);
    }
 
    void print() {
        printHelper(root, 3);
    }
 
    void removeConsonants() {
        removeHelper(root);
    }
};
 
int main() {
    srand(time(0));
 
    char str[] = "awesomeprogram";
 
    BinTree tree(str);
 
    cout << "initial tree:" << endl;
    tree.print();
    tree.removeConsonants();
    cout << "modified tree:" << endl;
    tree.print();
 
    return 0;
}
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.05.2015, 13:23

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

Построить дерево бинарного поиска и найти для него сумму нечетных значений узлов дерева
Ни как не могу придумать правильный метод который будет считать сумму нечетных значений узлов...

Удаление элементов из бинарного дерева
Доброго времени суток! Реализую обычное бинарное дерево (НЕ поиска) на базе массива (то еще...

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

Бинарное дерево. Поиск, вывод и удаление элементов из дерева
Задача следующая: Разработать программу, которая содержит информацию о реестре жилых помещений...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

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