Skip to content

Commit 3171767

Browse files
author
Alejandro Fernández Suárez
committed
bug fixed, AVL trees now working properly
1 parent 6276136 commit 3171767

File tree

2 files changed

+38
-23
lines changed

2 files changed

+38
-23
lines changed

include/avl.h

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ class AVL {
5151

5252
void erase(const T &x) {
5353
if (!isEmpty()) {
54-
tree = tree->erase(x);
55-
numNodes--;
54+
bool found = false;
55+
tree = tree->erase(x, found);
56+
if (found) numNodes--;
5657
}
5758
}
5859

@@ -64,7 +65,7 @@ class AVL {
6465
}
6566
}
6667

67-
private:
68+
public:
6869

6970
struct Node {
7071
Node *left, *right;
@@ -93,51 +94,58 @@ class AVL {
9394
return update();
9495
}
9596

96-
Node *erase(const T &x) {
97+
Node *erase(const T &x, bool &found) {
9798
if (value == x) {
99+
found = true;
98100
if (left == 0 && right == 0) {
99101
delete this;
100102
return 0;
101103
} else if (left == 0) {
104+
Node *aux = right;
102105
*this = *right;
103-
delete right;
106+
delete aux;
104107
} else if (right == 0) {
108+
Node *aux = left;
105109
*this = *left;
106-
delete left;
110+
delete aux;
107111
} else {
108112
// Tracing path to rightmost leaf of the left subtree
109113
std::stack<Node*> trace;
110114

111115
Node *current = left;
112-
while (current->right != 0) {
116+
while (current != 0) {
113117
trace.push(current);
114118
current = current->right;
115119
}
116120

121+
current = trace.top();
117122
value = current->value;
118123
Node *lsubtree = current->left;
119124
delete current;
125+
trace.pop();
120126

121-
if (trace.empty()) trace.push(left);
122-
123-
trace.top()->right = lsubtree;
124-
125-
do {
126-
trace.top()->update();
127+
if (trace.empty()) { left = lsubtree; }
128+
else {
129+
trace.top()->right = lsubtree;
127130
trace.pop();
128-
} while (!trace.empty());
131+
while (!trace.empty()) {
132+
current = trace.top();
133+
current->right = current->right->update();
134+
trace.pop();
135+
}
136+
}
129137
}
130138
return update();
131139
}
132140
else if (x < value) {
133141
if (left != 0) {
134-
left = left->erase(x);
142+
left = left->erase(x, found);
135143
return update();
136144
} else return this;
137145
}
138146
else {
139147
if (right != 0) {
140-
right = right->erase(x);
148+
right = right->erase(x, found);
141149
return update();
142150
} else return this;
143151
}

src/avl_demo.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ using namespace std;
55
using namespace alg;
66

77
const unsigned N = 4096*32;
8-
const unsigned N_ELEMS_TO_REMOVE = 4096*8;
8+
const unsigned N_ELEMS_TO_REMOVE = N-128; // Must be between 0 and N-1
99

1010
template <typename T>
1111
void printTreeStatus(const AVL<T> &t) {
@@ -40,20 +40,27 @@ int main()
4040
cout << "ERROR: Value " << values[idx] << " was inserted and not found!" << endl;
4141
}
4242

43-
cout << "Now removing " << N_ELEMS_TO_REMOVE << " random elements for the tree... ";
43+
cout << "Now removing a random element from the tree... ";
44+
unsigned idx = rand() % N;
45+
avl.erase(values[idx]);
46+
cout << "Done" << endl;
47+
48+
printTreeStatus(avl);
49+
50+
cout << "Now removing the root of the tree " << N_ELEMS_TO_REMOVE << " times... ";
4451
for (unsigned i = 0; i < N_ELEMS_TO_REMOVE; ++i) {
45-
unsigned idx = rand() % N;
46-
avl.erase(values[idx]);
52+
avl.erase(avl.root());
4753
}
4854
cout << "Done" << endl;
4955

5056
printTreeStatus(avl);
5157

52-
cout << "Do you want to see the GraphViz representation of the Tree (Y/n)? ";
58+
// Outputting to cerr so the output can be redirected with ./avl_demo 2> <name>.gvz
59+
cout << "Do you want to output the GraphViz representation of the tree to the cerr stream (Y/n)? ";
5360
char usrInput;
5461
cin >> usrInput;
55-
if (usrInput == 'Y' || usrInput == 'y') avl.toGraphViz(cout, "AVL");
56-
62+
if (usrInput == 'Y' || usrInput == 'y') avl.toGraphViz(cerr, "AVL");
63+
5764
return 0;
5865
}
5966

0 commit comments

Comments
 (0)