简体   繁体   English

二叉树的中序遍历遍历后给出垃圾值和分段错误

[英]Inorder traversal of binary tree gives garbage value and segmentation fault after traversal

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) Output:- 0 1 2 3 4 5 -786491 分段错误(核心转储)

As you can see from your output, you have traversed all elements, and the last element visited is d .从您的 output 可以看出,您已经遍历了所有元素,最后访问的元素是d

Now you are in this block, where ptr points to d :现在你在这个块中,其中ptr指向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] .好的, d没有孩子,你不进入if块,你计划访问的下一个节点是... STACK[-1]

Revise you algorithm.修改你的算法。 I recommend to avoid using goto as long as this is a notoriously bad practice.我建议避免使用goto ,只要这是一种非常糟糕的做法。

Your algorithm pops from the stack assuming there would always be something.假设总会有一些东西,您的算法会从堆栈中弹出。 But how should ptr then become NULL to end the second loop?但是 ptr 应该如何变成 NULL 来结束第二个循环呢?

As a consequence, your stack counter goes into the negative causing UB which (fortunately) expresses itself as a runtime error.结果,您的堆栈计数器变为负数,导致 UB(幸运的是)将自身表示为运行时错误。

Improvement 1: detect the end改进1:检测结束

You made the effort to write a push() .你努力写了一个push() Make the extra effort of writing a pop() .付出额外的努力编写一个pop() Make sure that either your algorithm checks for an empty stack or that pop() returns nullptr if the stack is empty:确保您的算法检查空堆栈,或者如果堆栈为空,则pop()返回nullptr

Node* pop()
{
    if (TOP>=0) { 
        return STACK[TOP--];
    }
    else {
        return nullptr;
    }
} 

Of course, replace the folowing sequences with ptr = pop();当然,将以下序列替换为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 .除了在goto之后使用 ptr 之外,所有pop()后面都是正在检查 null 的指针。 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.然后,当您运行该程序时,它将显示项目,但您会看到下溢结束了该过程。

Improvement 2: Get rid of the goto改进2:摆脱goto

We are in the 21st century: goto is no longer a fatality, and should better be avoided in C++ if possible .我们在 21 世纪: goto不再是致命的, 如果可能的话,最好在 C++ 中避免

An outer loop could elegantly replace the goto.外部循环可以优雅地替换 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"; 
}

Online demo在线演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM