I am trying to traverse a binary tree using a stack, the traversal is successful but the program at the end shows garbage values and segmentation fault error. I think it's not going to the top again and again but I m not able to fix this.
struct Node
{
int data;
Node *left;
Node *right;
Node(int x)
{
data = x;
left = NULL;
right = NULL;
}
};
Node *STACK[10] = { NULL };
int TOP = -1;
void push(Node *ptr)
{
if(TOP < 10) {
STACK[++TOP] = ptr;
}
}
void stackTraversal(Node *root)
{
Node *ptr = root; bool flag = false;
top:
while(ptr != NULL)
{
push(ptr);
ptr = ptr->left;
}
ptr = STACK[TOP];
TOP--;
while(ptr != NULL)
{
cout << ptr->data << " ";
if(ptr->right != NULL)
{
ptr = ptr->right;
flag = true;
break;
}
ptr = STACK[TOP];
TOP--;
}
if(flag)
goto top;
cout << "\nTHE END\n";
}
int main(int argc, char const *argv[])
{
Node *R = new Node(2);
Node *a = new Node(0);
Node *b = new Node(1);
Node *c = new Node(4);
Node *d = new Node(5);
Node *e = new Node(3);
R->right = c;
R->left = a;
a->right = b;
c->right = d;
c->left = e;
stackTraversal(R);
cout << endl;
return 0;
}
it is giving the following ouput.
Output:- 0 1 2 3 4 5 -786491 segmentation fault (core dumped)
As you can see from your output, you have traversed all elements, and the last element visited is d
.
Now you are in this block, where ptr
points to d
:
if(ptr->right != NULL)
{
ptr = ptr->right;
flag = true;
break;
}
ptr = STACK[TOP];
Ok, d
has no children, you don't enter the if
block, and the next node you plan to visit is... STACK[-1]
.
Revise you algorithm. I recommend to avoid using goto
as long as this is a notoriously bad practice.
Your algorithm pops from the stack assuming there would always be something. But how should ptr then become NULL to end the second loop?
As a consequence, your stack counter goes into the negative causing UB which (fortunately) expresses itself as a runtime error.
You made the effort to write a push()
. Make the extra effort of writing a pop()
. Make sure that either your algorithm checks for an empty stack or that pop()
returns nullptr
if the stack is empty:
Node* pop()
{
if (TOP>=0) {
return STACK[TOP--];
}
else {
return nullptr;
}
}
Of course, replace the folowing sequences with ptr = pop();
:
ptr = STACK[TOP];
TOP--;
All the pop()
are followed by the pointer being checked for null, except for use of ptr after the goto
. So you need to add an extra condition to avoid this situation:
if(flag && ptr)
goto top;
When you then run the programme, it will display the items, but you'll see that an underflow ends the process.
We are in the 21st century: goto
is no longer a fatality, and should better be avoided in C++ if possible .
An outer loop could elegantly replace the goto. You can then get rid of the flag as well:
void stackTraversal(Node *root)
{
...
while(ptr) // outer loop: no more goto
{
while(ptr) { // push the full left
push(ptr);
ptr = ptr->left;
}
ptr = pop(); // pop top node
while(ptr)
{
cout << ptr->data << " ";
cout.flush(); // in case of weird things happening afterwards
if(ptr->right) { // explore its right branch
ptr = ptr->right;
break; // this goes back to outer loop
}
else ptr = pop();
}
}
cout << "\nTHE END\n";
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.