Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/19: Рейтинг темы: голосов - 19, средняя оценка - 4.63
2 / 2 / 3
Регистрация: 10.04.2012
Сообщений: 22
1

Удаление элемента из бинарного дерева

24.01.2013, 17:32. Показов 3879. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
в программе выполняется пару ф-й, не работает удаление элемента (в меню пункт 1), должен удалить узел где длина кода более 5, при попытке удалить крайней листок не имеющий потомков выдает, а ежели удалять элементы имеющие потомков, то когда печатает дерево выдает ту же ошибку, даю файл с деревом и ВЕСЬ код программы.

т.е. не работают: void DeleteNode (Tree ** root_adr);

код сбалансированного дерева " balanced[1]":
h 001 d 002 l 003 b 004 f 005 j 006 n 007 a 008 c 009 e 010 g 011 i 0121212 k 013 m 014 o 015
код не сбалансированного дерева "not balanced[2]" :
d 01 b 02 j 03 a 04 c 05 g 06 m 007 f 080808 h 09 l 10 n 11 e 12 o 13

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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct key_combinations
{
    char *key;
    char *combination;
} KEY_COMBINATION;
 
 
typedef struct tree
{
    KEY_COMBINATION kc;
    struct tree *left,*right;
}Tree;
 
Tree *root;
Tree ** stack;   
 
void AddNode (Tree * proot, Tree * pnew) ;
void GetData ();
void PrintTree();
    void ShowTree(Tree *rooot, int lvl);
    void PutTree(Tree *rooot);
void ifMore(Tree *rooot);
    void DeleteNode (Tree ** root_adr);
        void FreeNode (Tree * node) ;
int TreeHeight(Tree * proot);
void DigitNumber(Tree * proot);
void RightToTop(Tree **root_adr);
void DeleteTree(Tree *rooot) ;
 
int main()
{ 
    
    GetData ();
    PrintTree();
    int menu=1,len=0;
     while(menu>0)
     {
    printf("\n\n delete where len>5 [1]\n right ot top [2] \n iteretion funk [3] \n free && exit [0] \n ");
        scanf("%d",&menu);
    switch(menu)
    {
    case 1:
        ifMore(root);
        PrintTree();
    break;
    case 2:
            
            len=TreeHeight(root);
            printf("\n Tree height = %d with root : %s",len,root->kc.key);
            RightToTop(&root);
            len=TreeHeight(root);
            printf("\n Tree height = %d with root : %s",len,root->kc.key);
    break;
    case 3:
            stack=(Tree **)calloc(TreeHeight(root), sizeof(Tree *));
            DigitNumber(root); 
    break;
    case 0:
        DeleteTree(root);
    
    break;  
    }
    }
 
return 0;
}
 
void GetData ()
{
    Tree * pel;
    KEY_COMBINATION * pkc;
 
    char bufk[3],bufc[25];
    FILE* f;
    
    pkc = (KEY_COMBINATION *)malloc(sizeof(KEY_COMBINATION));
    
    int choise;
    printf("choose file balanced[1] not balanced[2] :   ");
    scanf("%d",&choise);
         
    if(choise==2)
        f = fopen("TreeNB","r");
    else
        f = fopen("TreeB","r");
 
    while(fscanf(f,"%s%s",bufk,bufc)!=EOF)
    {   
        //printf("\n %s %s",bufk,bufc);
        pkc->key = (char * ) malloc(strlen(bufk)+1);
        strcpy(pkc->key, bufk);
 
        pkc->combination =(char * ) malloc(strlen(bufc)+1);
        strcpy(pkc->combination, bufc);
 
        pel = (Tree *)malloc(sizeof(Tree));
        pel->kc = * pkc;
 
        pel->left = NULL;
        pel->right = NULL;
 
        AddNode(root,pel);
    }
}
 
void AddNode (Tree * proot, Tree * pnew)
{
        if (root == NULL)
           root = pnew;
        else
            if (strcmp(proot->kc.key, pnew->kc.key)>0)
                if (proot->left == NULL)
                    proot->left = pnew;
                else
                    AddNode(proot->left, pnew);
            else
                if (proot->right == NULL)
                    proot->right = pnew;
                else
                    AddNode(proot->right, pnew);
    }
 
void PrintTree()
{
    puts("\n===============================");
    PutTree(root);
    puts("\n===============================\n");
    ShowTree(root,1);
    puts("===============================");
}
 
void ShowTree(Tree *rooot, int lvl)
{
    if(rooot==NULL)
        return;
 
    ShowTree(rooot->right,lvl+1);
          printf("%*c%s\n", lvl*3,' ', rooot->kc.key);
    ShowTree(rooot->left,lvl+1);
}
 
void PutTree(Tree *rooot)
{
    if(rooot==NULL)
        return;
             printf("\n\t%s -\t%s", rooot->kc.key, rooot->kc.combination);
    PutTree(rooot->left);
    PutTree(rooot->right);
}
 
void ifMore(Tree *rooot)
{
 
    if(rooot==NULL)
        return;
    if(strlen(rooot->kc.combination)>5)
        {
            printf("found %s",rooot->kc.key);
            printf("\n %s-%s", rooot->kc.key, rooot->kc.combination);
           DeleteNode(&rooot);
           ifMore(rooot);
        }
    ifMore(rooot->left);
    ifMore(rooot->right);
}
 
void FreeNode (Tree * node)
{   
    free(node->kc.key);
    free(node->kc.combination);
    free(node);
}
 
int TreeHeight(Tree * proot) 
    {  
            int lh,rh;
            if (proot == NULL) 
            return 0;
           lh = TreeHeight(proot->left);        
           rh = TreeHeight(proot->right);      
           return  lh > rh ? lh+1 : rh+1;  
    }
 
void DigitNumber(Tree * proot)
{
int i=0;
Tree  * pdel = root, * pnext;
 
  while (pdel!= NULL) {  
       if (pdel->left!= NULL) 
  {         pnext = pdel->left;      
        if (pdel->right!= NULL)                 
               stack[++i] = pdel->right;  
                 }
                  else  
        if (pdel->right!= NULL)
           pnext = pdel->right;         
        else
            pnext = stack[i--];   
    int n = strlen(pdel->kc.combination);
    printf("%s -%s - digit number =  %d\n ",pdel->kc.key,pdel->kc.combination,n);
     pdel = pnext;                    
  }
 
}
 
void RightToTop(Tree **root_adr)
    {
 
        Tree *proot = *root_adr,*pright = *root_adr,*prev;
 
        while(pright->right!=NULL)
            {
                prev=pright;
                pright=pright->right;
            }
 
        prev->right=NULL;
        pright->left=proot;
        *root_adr=pright;
 
    }
 
void DeleteNode (Tree ** root_adr)
{ 
   Tree * proot = *root_adr, * pright, * padd;
     int cmp, subtr;
  if (proot == NULL)   return;       
    
  if (proot->left == NULL && proot->right == NULL) 
       subtr = 0;                      
    else if (proot->left == NULL)
           subtr = 1;
        else if (proot->right == NULL)
                subtr = -1;
             else
                subtr = 2;
    switch (subtr) 
    {                         
      case 0:                         
        *root_adr = NULL;  
         break;
      case -1:              
        *root_adr = proot->left; 
         break;
      case 1:           
         *root_adr = proot->right; 
        break;
      case 2:                   
        *root_adr = proot->left; 
            pright = proot->left->right;  
        padd = proot->left->right=proot->right ;
        proot->right=NULL;     
        while (padd->left!= NULL)
            padd = padd->left;
        padd->left = pright;  
        break;   
    }    
    FreeNode(proot);
    printf(" free..");    
  }
 
void DeleteTree(Tree *rooot)  
{
    if(rooot==NULL)
        return;
    DeleteTree(rooot->left);
    DeleteTree(rooot->right);
    free(rooot);
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.01.2013, 17:32
Ответы с готовыми решениями:

Удаление узла бинарного дерева
Бьюсь над задачей битый час, в функцию передаю указатель на узел, который и хотим удалить. И в...

Удаление бинарного дерева и освобождение памяти
Работаю с бинарным деревом поиска.Создал простую структуру а также объявил тип указателя на...

Удаление элемента из бинарного дерева
Ругается компилятор в Visual Studio при выполнении кода удаления элемента, а именно в том месте,...

удаление элемента бинарного дерева
как удалить элемент бинарного дерева,имеющий 2 потомка?(например дерево (2)-(7 и 0)-(4 и...

8
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
24.01.2013, 18:28 2
у меня в прошлом семестре была лаба в которой нужно было реализировать некое подобие базы данных основанную на деревьях.
так вот, для удаления я добавил в структуру еще одно поле, которое обозначало удален ли элемент из дерева.
то есть, фактически информация не удалялась, и, при желании ее можно было востановить.
ну и соответсвенно, когда выполнялся поиск, вывод, редактирование все основывалось на этом флажке. если он установлен - увы нету такого элемента, если неустановлен - все ок - ищим, выводим, редактируем.

может я просто ленивый, но помоему сделать удаление для односвязного дерева(то есть когда есть указатели left, right, но нету parent(указатель на родительский элемент) довольно сложно.
0
2 / 2 / 3
Регистрация: 10.04.2012
Сообщений: 22
24.01.2013, 18:47  [ТС] 3
Мне такое не подойдет, у меня преподаватель очень придирчивый поэтому имеет следовать в ТС. Кстати удаления ф-я как бы правильная, просто где-то не происходит правильно удаление или замена и комп обращается к несуществующему элемента, но где ошибка не знаю ..

Добавлено через 11 минут
забыл дописать, выдает ошибку segmentation fault 11
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
24.01.2013, 19:04 4
ihor, нужно связать предыдущее звено с текущим а потом освободить память. Это делается так: если след. левый потомок == значению нашего удал. элемента, то правое поддерево тек. элемента становится текущим левым потомком (встает на место удал. элемента), а указатель на левое ищет место в новом дереве начиная с правого поддерева удал. узла. После всех операций память под удал. элемент освобождается.
Лучше всего, попробуйте нарисовать это на бумаге, представить как должно быть.
1
2 / 2 / 3
Регистрация: 10.04.2012
Сообщений: 22
25.01.2013, 22:52  [ТС] 5
Да даже если я удаляю крайней элемент, у которого нет потомков, все равно выдает ошибку segmentetion fault 11
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
25.01.2013, 22:58 6
ihor, покажите, как удаляете. Вы указатель то хоть на него обнуляете?
0
2 / 2 / 3
Регистрация: 10.04.2012
Сообщений: 22
26.01.2013, 17:50  [ТС] 7
вот ф-я удаления
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_adr)
{ 
   Tree * proot = *root_adr, * pright, * padd;
     int cmp, subtr;
  if (proot == NULL)   return;       
    
  if (proot->left == NULL && proot->right == NULL) 
       subtr = 0;                      
    else if (proot->left == NULL)
           subtr = 1;
        else if (proot->right == NULL)
                subtr = -1;
             else
                subtr = 2;
    switch (subtr) 
    {                         
      case 0:                         
        *root_adr = NULL;  
         break;
      case -1:              
        *root_adr = proot->left; 
         break;
      case 1:           
         *root_adr = proot->right; 
        break;
      case 2:                   
        *root_adr = proot->left; 
            pright = proot->left->right;  
        padd = proot->left->right=proot->right ;
        proot->right=NULL;     
        while (padd->left!= NULL)
            padd = padd->left;
        padd->left = pright;  
        break;   
    }    
    FreeNode(proot);
    printf(" free..");    
  }
и ф-я фри
C
1
2
3
4
5
6
void FreeNode (Tree * node)
{   
    free(node->kc.key);
    free(node->kc.combination);
    free(node);
}
0
2 / 2 / 3
Регистрация: 10.04.2012
Сообщений: 22
29.01.2013, 19:45  [ТС] 8
Ну народ ! HELP !
0
0 / -1 / 0
Регистрация: 11.01.2015
Сообщений: 34
15.05.2016, 15:29 9
C
1
2
3
4
5
6
7
8
9
void Del(ELT *q)
{
     if(q!=NULL)
      {
        Del(q->left);
        Del(q->reght);
        free(q);
      }
}
0
15.05.2016, 15:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.05.2016, 15:29
Помогаю со студенческими работами здесь

Реализовать удаление элемента бинарного дерева
Подскажите пожалуйста, нужен метод, который удаляет элемент( и возвращает этот элемент) из...

Удаление элемента из сбалансированого бинарного дерева
Задание: написать программу, которая создает сбалансированное бинарное дерево, написать процедуру,...

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

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


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru