AVL tree

I was trying to write code to implement AVL tree, but I was getting a segmentation fault when I try to insert more than one element, I changed some functions but still the same error is coming.

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
#include <iostream>
#include<stdlib.h>

using namespace std;

template<class t>
class bstn{
    public:
    t data;
    bstn *l,*r,*p;
    int h;
};

template<class t>
class bst{
    bstn<t> *newn,*tp,*tl,*tr,*t1,*root;
    public:
    bst(){
        root=NULL;
    }
    bool search(t,bstn<t>*);
    void insert(t);
    void remove(t);
    void rr(t);
    void lr(t);
    void traverse(t,bstn<t>*);
    void inch(bstn<t>*);
    void trav(bstn<t>*);
    bool s(t x){
        return search(x,root);
    }
};

template<class t>bool bst<t>::search(t x,bstn<t> *temp){
    if(root==NULL){
        return 0;
    }
    else if(temp->data!=x&&temp->l==NULL&&root->r==NULL){
        return 0;
    }
    else if(temp->data<x)
        return search(x,temp->r);
    else if(temp->data>x)
        return search(x,temp->l);
    return 1;
}//end of search function

template<class t>void bst<t>::traverse(t x,bstn<t> *temp){
    t1=temp;
    if(temp->data<x&&temp->r!=NULL)
        traverse(x,temp->r);
    else if(temp->data>x&&temp->l!=NULL)
        traverse(x,temp->r);
}//end of traverse function

template<class t>void bst<t>::rr(t x){
    traverse(x,root);
    tp=t1->p;
    tl=t1->l;
    if(tp->data<tl->data)
        tp->r=tl;
    else
        tp->l=tl;
    tl->p=tp;
    t1->p=tl;
    t1->l=tl->r;
    tl->r=t1;
}

template<class t>void bst<t>::lr(t x){
    traverse(x,root);
    tp=t1->p;
    tr=t1->r;
    if(tp->data<tr->data)
        tp->r=tr;
    else
        tp->l=tr;
    tr->p=tp;
    t1->p=tr;
    t1->r=tr->l;
    tr->l=t1;
}

template<class t>void bst<t>::insert(t x){
    if(s(x))
        cout<<"element is already present"<<endl;
    else{
        newn=new bstn<t>;
        newn->data=x;
        newn->l=NULL;
        newn->r=NULL;
        newn->h=0;
        if(root==NULL)
            root=newn;
        else{
        traverse(x,root);
        if(x<t1->data){
            t1->l=newn;
        }
        else{
            t1->r=newn;
        }
        newn->p=t1;
        inch(newn);
        trav(newn);
        }
        cout<<"Element is inserted."<<endl;
    }
}//end of insert function

template<class t>void bst<t>::inch(bstn<t> *temp){
    if(temp!=root){
        if((temp->data<temp->p->data&&temp->p->r==NULL)||(temp->data>temp->p->data&&temp->p->l==NULL)){
        temp->p->h=temp->p->h+1;
        inch(temp->p);
        }
    else if((temp->data<temp->p->data&&temp->h>temp->p->r->h)||(temp->data>temp->p->data&&temp->h>temp->p->l->h)){
        temp->p->h=temp->p->h+1;
        inch(temp->p);
        }
    }
}

template<class t>void bst<t>::trav(bstn<t> *temp){
    if(temp!=root){
        if(((temp->l->h)-(temp->r->h))*((temp->p->l->h)-(temp->p->r->h))<0){
            if(temp->l->h-temp->r->h<0)
                rr(temp->data);
            else
                lr(temp->data);
        }
    }
    if((temp->l->h)-(temp->r->h<-1))
        rr(temp->data);
    else if((temp->l->h)-(temp->r->h>1))
        lr(temp->data);
    if(temp!=root)
        trav(temp->p);
}

template<class t>void bst<t>::remove(t x){
    traverse(x,root);
    if(t1->data!=x)
        cout<<"Element not found"<<endl;
    else{
        if(t1==root){
            if(t1->l==NULL&&t1->r==NULL)
                root=NULL;

            else if(t1->l==NULL&&t1->r!=NULL){
                t1->r->p=NULL;
                root=t1->r;
            }
            else if(t1->l!=NULL&&t1->r==NULL){
                t1->l->p=NULL;
                root=t1->l;
            }
            else{
                for(newn=root->r;newn->l!=NULL;newn=newn->l);
                newn->l=root->l;
                if(newn!=root->r){
                    newn->p->l=NULL;
                    newn->r=root->r;
                }
                else{
                    newn->r=NULL;
                }
                newn->p=NULL;
                root=newn;
                for(newn=root->r;newn->l!=NULL;newn=newn->l);
                trav(newn);
            }
        }

        else if(t1->l==NULL&&t1->r==NULL){
            if(t1->p->data<x)
                t1->p->r=NULL;
            else
                t1->p->l=NULL;
            trav(t1->p);
        }
        else if(t1->l==NULL&&t1->r!=NULL){
            if(t1->p->data<x)
                t1->p->r=t1->r;
            else
                t1->p->l=t1->r;
            t1->r->p=t1->p;
            trav(t1->p);
        }
        else if(t1->l!=NULL&&t1->r==NULL){
            if(t1->p->data<x)
                t1->p->r=t1->l;
            else
                t1->p->l=t1->l;
            t1->l->p=t1->p;
            trav(t1->p);
        }
        else{
            for(newn=t1->r;newn->l!=NULL;newn=newn->l);

            newn->p=t1->p;
            newn->l=t1->l;

            if(t1->data>t1->p->data){
                t1->p->r=newn;
            }
            else{
                t1->p->l=newn;
            }
            if(newn!=t1->r){
                newn->p->l=NULL;
                newn->r=t1->r;
            }
            else{
                newn->r=NULL;
            }
            for(newn=t1->r;newn->l!=NULL;newn=newn->l);
            trav(newn);
        }
    delete(t1);
    cout<<x<<" is removed."<<endl;
    }
}

int main()
{
    bst<int> avl;
    char c;
    do{
        cout<<"1.Insert\n2.Remove\n3.Search\n4.Exit\nChoose an option :";
        int x,y;
        cin>>x;
        switch(x){
            case 1:
            cout<<"What do you want to insert :";
            cin>>y;
            avl.insert(y);
            break;
            case 2:
            cout<<"What do you want to remove :";
            cin>>y;
            avl.remove(y);
            break;
            case 3:
            cout<<"What do you want to search :";
            cin>>y;
            if(avl.s(y))
                cout<<"Element found."<<endl;
            else
                cout<<"Element not found"<<endl;
            break;
            case 4:
            exit(0);
            default:
            cout<<"You didn't choose an existing option, please try again."<<endl;
        }
        cout<<"Do you want to continye[y/n] :";
        cin>>c;
    }while(c=='y'||c=='Y');
    return 0;
}

Where the output was:
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :1
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :2
Segmentation fault (core dumped)

Can anyone please explain why this is happening?
Last edited on
You should probably not use root inside the search function.
Sorry, I didn't understand. Where should I start searching without using root?
I think you should use temp and not root inside the search function. The search should of course start at the root.
Last edited on
I've changed code to
1
2
3
4
5
6
7
8
9
10
11
12
13
template<class t>bool bst<t>::search(t x,bstn<t> *temp){
    if(temp==NULL){
        return 0;
    }
    else if(temp->data!=x&&temp->l==NULL&&root->r==NULL){
        return 0;
    }
    else if(temp->data<x)
        return search(x,temp->r);
    else if(temp->data>x)
        return search(x,temp->l);
    return 1;
}//end of search function 

but the output didn't change, I think keeping temp or root doesn't change output, since we are checking for all of them in first else if block.
You are still using root in the search function.

You have another problem on line 53. You are using temp->r instead of temp->l.

Last edited on
I'm sorry I didn't see that, thanks for showing me but still the same error's coming.
Can anyone please tell me why is this happening?
In the trav function you assume that the temp->l and temp->r is not null. This is never the case when called from the insert function.
I've changed trav and some other functions for convenience, combining 'lr' and 'rr' into a single 'rot' function

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
template<class t>void bst<t>::rot(t x){
    traverse(x,root);
    tp=t1->p;
    if(bf(t1)>0){
        tl=t1->l;
        if(tp->data<tl->data)
            tp->r=tl;
        else
            tp->l=tl;
        tl->p=tp;
        t1->p=tl;
        t1->l=tl->r;
        tl->r=t1;
    }
    else if(bf(t1)<0){
        tr=t1->r;
        if(tp->data<tr->data)
            tp->r=tr;
        else
            tp->l=tr;
        tr->p=tp;
        t1->p=tr;
        t1->r=tr->l;
        tr->l=t1;
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<class t>void bst<t>::trav(bstn<t> *temp){
    if(bf(temp)*bf(temp->p)<-1||bf(temp)<-1||bf(temp)>1)
        rot(temp->data);
    if(temp!=root)
        trav(temp->p);
}

template<class t>int bst<t>::bf(bstn<t> *temp){
    if(temp->l==NULL&&temp->r==NULL)
        return 0;
    else if(temp->l==NULL&&temp->r!=NULL)
        return (-1*(temp->r->h+1));
    else if(temp->l!=NULL&&temp->r==NULL)
        return temp->l->h+1;
    else
        return temp->l->h-temp->r->h;
}

but still the same error continues to come??
I think it is time that you learn how to use a debugger.
Oh! I was doing the same mistake again and again(I didn't get how to use the debugger, but now I could find a way to use it), when (temp==root) it doesn't have any parent element, I've changed it to
1
2
3
4
5
6
7
8
9
template<class t>void bst<t>::trav(bstn<t> *temp){
    if(temp!=root){
        if(bf(temp)*bf(temp->p)<-1||bf(temp)<-1||bf(temp)>1)
            rot(temp->data);
        trav(temp->p);
    }
    else if(bf(temp)<-1||bf(temp)>1)
        rot(temp->data);
}

and I have also noticed error in the sequene insert 1->insert 2->remove 1->insert 1->search 3 I've also changed search function as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<class t>bool bst<t>::search(t x,bstn<t> *temp){
    if(root==NULL){
        return 0;
    }
    else if(temp->data!=x&&temp->l==NULL&&temp->r==NULL){
        return 0;
    }
    else if(temp->data<x&&temp->r!=NULL)
        return search(x,temp->r);
    else if(temp->data>x&&temp->l!=NULL)
        return search(x,temp->l);
    else if(temp->data<x&&temp->r==NULL)
        return 0;
    else if(temp->data>x&&temp->l==NULL)
        return 0;
    return 1;
}//end of search function 

program was running normally but I've noticed that I didn't change the height of elements after rotating, therefore I've changed the rot function into
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
template<class t>void bst<t>::rot(t x){
    traverse(x,root);
    tp=t1->p;
    if(bf(t1)>0){
        tl=t1->l;
        if(tp->data<tl->data)
            tp->r=tl;
        else
            tp->l=tl;
        tl->p=tp;
        t1->p=tl;
        t1->l=tl->r;
        tl->r=t1;
        inch(t1->l);
    }
    else if(bf(t1)<0){
        tr=t1->r;
        if(tp->data<tr->data)
            tp->r=tr;
        else
            tp->l=tr;
        tr->p=tp;
        t1->p=tr;
        t1->r=tr->l;
        tr->l=t1;
        inch(t1->r);
    }

}

and inch function as
1
2
3
4
5
6
7
8
9
10
11
12
template<class t>void bst<t>::inch(bstn<t> *temp){
    if(temp!=root){
        if((temp->data<temp->p->data&&temp->p->r==NULL)||(temp->data>temp->p->data&&temp->p->l==NULL)){
        temp->p->h=temp->h+1;
        inch(temp->p);
        }
    else if((temp->data<temp->p->data&&temp->h>temp->p->r->h)||(temp->data>temp->p->data&&temp->h>temp->p->l->h)){
        temp->p->h=temp->h+1;
        inch(temp->p);
        }
    }
}
Is the logic in the rot and inch functions to change the height correct?
I still did many changes and used the debugger, but I am not able to understand why I am not able to delete and insert the same element especially when it is middle element with more than 4 elements
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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#include <iostream>
#include<stdlib.h>

using namespace std;

template<class t>
class bstn{
    public:
    t data;
    bstn *l,*r,*p;
    int h;
};

template<class t>
class bst{
    bstn<t> *newn,*tp,*tl,*tr,*t1,*root;
    public:
    bst(){
        root=NULL;
    }
    bool search(t);
    void insert(t);
    void remove(t);
    void rot(t);
    void traverse(t,bstn<t>*);
    void inch(bstn<t>*);
    void trav(bstn<t>*);
    int bf(bstn<t>*);
    void dh(bstn<t> *temp){
        if(temp==NULL)
            cout<<"NULL"<<endl;
        else{
            cout<<temp->data<<endl;
            cout<<temp->h<<endl;
        }
    }
    void r(){
        dh(root);
    }
    void left(t x){
        traverse(x,root);
        dh(t1->l);
    }
    void right(t x){
        traverse(x,root);
        dh(t1->r);
    }
};

template<class t>bool bst<t>::search(t x){
    if(root==NULL)
        return 0;
    else{
        traverse(x,root);
        if(t1->data==x)
            return 1;
        else
            return 0;
    }
}//end of search function

template<class t>void bst<t>::traverse(t x,bstn<t> *temp){
    t1=temp;
    if(temp->data<x&&temp->r!=NULL)
        traverse(x,temp->r);
    else if(temp->data>x&&temp->l!=NULL)
        traverse(x,temp->l);
}//end of traverse function

template<class t>void bst<t>::rot(t x){
    traverse(x,root);
    if(t1==root){
        tr=t1->r;
        tl=t1->l;
        if(bf(t1)>0){
            t1->l=tl->r;
            tl->r=t1;
            t1->p=tl;
            root=tl;
            inch(t1);
        }
        else if(bf(t1)<0){
            t1->r=tr->l;
            tr->l=t1;
            t1->p=tr;
            root=tr;
            inch(t1);
        }
    }
    else{
        tp=t1->p;
        if(bf(t1)>0){
            tl=t1->l;
            if(tp->data<tl->data)
                tp->r=tl;
            else
                tp->l=tl;
            tl->p=tp;
            t1->p=tl;
            t1->l=tl->r;
            tl->r=t1;
            inch(t1);
        }
        else if(bf(t1)<0){
            tr=t1->r;
            if(tp->data<tr->data)
                tp->r=tr;
            else
                tp->l=tr;
            tr->p=tp;
            t1->p=tr;
            t1->r=tr->l;
            tr->l=t1;
            inch(t1);
        }

    }
}

template<class t>void bst<t>::insert(t x){
    if(search(x))
        cout<<"element is already present"<<endl;
    else{
        newn=new bstn<t>;
        newn->data=x;
        newn->l=NULL;
        newn->r=NULL;
        newn->h=0;
        if(root==NULL)
            root=newn;
        else{
        traverse(x,root);
        if(x<t1->data){
            t1->l=newn;
        }
        else{
            t1->r=newn;
        }
        newn->p=t1;
        inch(t1);
        trav(t1);
        }
        cout<<"Element is inserted."<<endl;
    }
}//end of insert function

template<class t>void bst<t>::inch(bstn<t> *temp){
    if(temp->r==NULL&&temp->l==NULL)
        temp->h=0;
    else if(bf(temp)>0)
        temp->h=temp->l->h+1;
    else
        temp->h=temp->r->h+1;
    if(temp!=root)
        inch(temp->p);
}

template<class t>void bst<t>::trav(bstn<t> *temp){
    if(temp!=root){
        if(bf(temp)*bf(temp->p)<-1||bf(temp)<-1||bf(temp)>1)
            rot(temp->data);
        trav(temp->p);
    }
    else if(bf(temp)<-1||bf(temp)>1)
        rot(temp->data);
}

template<class t>int bst<t>::bf(bstn<t> *temp){
    if(temp->l==NULL&&temp->r==NULL)
        return 0;
    else if(temp->l==NULL&&temp->r!=NULL)
        return (-1*(temp->r->h+1));
    else if(temp->l!=NULL&&temp->r==NULL)
        return temp->l->h+1;
    else
        return temp->l->h-temp->r->h;
}

template<class t>void bst<t>::remove(t x){
    traverse(x,root);
    if(t1->data!=x)
        cout<<"Element not found"<<endl;
    else{
        if(t1==root){
            if(t1->l==NULL&&t1->r==NULL)
                root=NULL;

            else if(t1->l==NULL&&t1->r!=NULL){
                t1->r->p=NULL;
                root=t1->r;
            }
            else if(t1->l!=NULL&&t1->r==NULL){
                t1->l->p=NULL;
                root=t1->l;
            }
            else{
                for(newn=root->r;newn->l!=NULL;newn=newn->l);
                t1->l->p=newn;
                newn->l=root->l;
                if(newn!=root->r){
                    newn->p->l=NULL;
                    newn->r=root->r;
                }
                newn->p=NULL;
                root=newn;
                if(root->r!=NULL){
                    for(newn=root->r;newn->l!=NULL;newn=newn->l);
                    inch(newn);
                    trav(newn);
                }
                else{
                    inch(root);
                    trav(root);
                }
            }
        }

        else if(t1->l==NULL&&t1->r==NULL){
            if(t1->p->data<x)
                t1->p->r=NULL;
            else
                t1->p->l=NULL;
            inch(t1->p);
            trav(t1->p);
        }
        else if(t1->l==NULL&&t1->r!=NULL){
            if(t1->p->data<x)
                t1->p->r=t1->r;
            else
                t1->p->l=t1->r;
            t1->r->p=t1->p;
            inch(t1->p);
            trav(t1->p);
        }
        else if(t1->l!=NULL&&t1->r==NULL){
            if(t1->p->data<x)
                t1->p->r=t1->l;
            else
                t1->p->l=t1->l;
            t1->l->p=t1->p;
            inch(t1->p);
            trav(t1->p);
        }
        else{
            for(newn=t1->r;newn->l!=NULL;newn=newn->l);
            newn->l=t1->l;
            t1->l->p=newn;
            if(t1->data>t1->p->data){
                t1->p->r=newn;
            }
            else{
                t1->p->l=newn;
            }
            if(newn!=t1->r){
                newn->p->l=NULL;
                newn->r=t1->r;
            }
            newn->p=t1->p;
            for(newn=t1->r;newn->l!=NULL;newn=newn->l);
            inch(newn);
            trav(newn);
        }
    delete(t1);
    cout<<x<<" is removed."<<endl;
    }
}

int main(){
    bst<int> avl;
    char c;
    do{
        cout<<"1.Insert\n2.Remove\n3.Search\n4.Exit\nChoose an option :";
        int x,y;
        cin>>x;
        switch(x){
            case 1:
            cout<<"What do you want to insert :";
            cin>>y;
            avl.insert(y);
            break;
            case 2:
            cout<<"What do you want to remove :";
            cin>>y;
            avl.remove(y);
            break;
            case 3:
            cout<<"What do you want to search :";
            cin>>y;
            if(avl.search(y))
                cout<<"Element found."<<endl;
            else
                cout<<"Element not found"<<endl;
            break;
            case 4:
            exit(0);
            case 9:
            avl.r();
            break;
            case 8:
            cin>>x;
            avl.left(y);
            break;
            case 7:
            cin>>x;
            avl.right(y);
            break;
            default:
            cout<<"You didn't choose an existing option, please try again."<<endl;
        }
        cout<<"Do you want to continye[y/n] :";
        cin>>c;
    }while(c=='y'||c=='Y');
    return 0;
}
And the output is
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :1
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :2
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :3
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :4
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :5
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :6
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :7
Element is inserted.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :2
What do you want to remove :4
4 is removed.
Do you want to continye[y/n] :y
1.Insert
2.Remove
3.Search
4.Exit
Choose an option :1
What do you want to insert :4
Segmentation fault (core dumped)

The debugger's showing the same function name (inch();) twenty times, I checked the program by printing the root element and left and right elements of all the elements and everything looks normal(I did the program in linux)
Last edited on
Can anyone please tell the reason?
It's gonna be difficult for anyone to wade through that code. If you had names that meant something, and your class data members weren't mostly things that should be local variables in member functions and you had a useful comment here and there, it might be a bit easier. Of the 6 data members in bst, only one of them (root) actually belongs.
Topic archived. No new replies allowed.