简体   繁体   English

后序树遍历中的分段错误

[英]Segmentation Fault in Post-order Tree traversal

I'm trying to implement postorder traversal of a tree using a single stack. 我正在尝试使用单个堆栈来实现树的后顺序遍历。 I'm getting a segmentation fault now Can someone explain me the reason? 我现在遇到细分错误,有人可以向我解释原因吗? 图片在这里

This is the algorithm: 这是算法:

1.1 Create an empty stack
2.1 Do following while root is not NULL
    a) Push root's right child and then root to stack.
    b) Set root as root's left child.
2.2 Pop an item from stack and set it as root.
    a) If the popped item has a right child and the right child 
       is at top of stack, then remove the right child from stack,
       push the root back and set root as root's right child.
    b) Else print root's data and set root as NULL.
2.3 Repeat steps 2.1 and 2.2 while stack is not empty.

Example

. Right child of 1 exists. 存在1个右孩子。 Push 3 to stack. 按3进行堆叠。 Push 1 to stack. 按1进行堆叠。 Move to left child. 移到左孩子。 Stack: 3, 1 堆叠:3,1

  1. Right child of 2 exists. 存在2的右子。 Push 5 to stack. 按5进行堆叠。 Push 2 to stack. 按2进行堆叠。 Move to left child. 移到左孩子。 Stack: 3, 1, 5, 2 堆叠:3,1,5,2

  2. Right child of 4 doesn't exist. 右孩子4不存在。 ' Push 4 to stack. '按4进行堆叠。 Move to left child. 移到左孩子。 Stack: 3, 1, 5, 2, 4 堆叠:3,1,5,2,4

  3. Current node is NULL. 当前节点为NULL。 Pop 4 from stack. 从堆栈中弹出4。 Right child of 4 doesn't exist. 右孩子4不存在。 Print 4. Set current node to NULL. 打印4.将当前节点设置为NULL。 Stack: 3, 1, 5, 2 堆叠:3,1,5,2

  4. Current node is NULL. 当前节点为NULL。 Pop 2 from stack. 从堆栈中弹出2。 Since right child of 2 equals stack top element, pop 5 from stack. 由于2的右子元素等于堆栈顶部元素,因此从堆栈中弹出5。 Now push 2 to stack. 现在将2推入堆栈。
    Move current node to right child of 2 ie 5 Stack: 3, 1, 2 将当前节点移到2的右子节点,即5堆栈:3,1,2

  5. Right child of 5 doesn't exist. 5个合适的孩子不存在。 Push 5 to stack. 按5进行堆叠。 Move to left child. 移到左孩子。 Stack: 3, 1, 2, 5 堆叠:3,1,2,5

  6. Current node is NULL. 当前节点为NULL。 Pop 5 from stack. 从堆栈中弹出5。 Right child of 5 doesn't exist. 5个合适的孩子不存在。 Print 5. Set current node to NULL. 打印5.将当前节点设置为NULL。 Stack: 3, 1, 2 堆叠:3,1,2

  7. Current node is NULL. 当前节点为NULL。 Pop 2 from stack. 从堆栈中弹出2。 Right child of 2 is not equal to stack top element. 2的右子元素不等于堆栈顶部元素。 Print 2. Set current node to NULL. 打印2.将当前节点设置为NULL。 Stack: 3, 1 堆叠:3,1

  8. Current node is NULL. 当前节点为NULL。 Pop 1 from stack. 从堆栈中弹出1。 Since right child of 1 equals stack top element, pop 3 from stack. 由于右子元素1等于堆栈顶部元素,因此从堆栈中弹出3。 Now push 1 to stack. 现在按1进行堆叠。 Move current node to right child of 1 ie 3 Stack: 1 将当前节点移到1的右子节点,即3堆栈:1

  9. Repeat the same as above steps and Print 6, 7 and 3. Pop 1 and Print 1. 重复上述步骤,然后打印6、7和3。弹出1和打印1。

Code : Problem lies in Ipostorder function ..if you comment and run you won't get a segmentation fault. 代码 :问题出在Ipostorder函数中。.如果您注释并运行,则不会出现分段错误。

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
    int data;
    struct node *left,*right;

}node;
typedef struct stack
{
    node *data;
    struct stack *next;
}stack;
stack *top=NULL;
int isEmpty()
{
    if(top==NULL)
        return 1;
    else
        return 0;
}

node *pop()
{
    node *p=top->data;
    top=top->next;
    return p;
}
void push(node *num)
{
    stack *p;
    p=malloc(sizeof(stack));
    p->data=num;
    p->next=top;
    top=p;

}


node *newNode(int key)
{
    node *p=malloc(sizeof(node));
    p->left=p->right=NULL;
    p->data=key;
    return p;
}
void insert(node **head,int key)
{
    node *p;
    p=*head;
    if(!p)
    {
        *head=newNode(key);
        return;
    }
    if(p->data>key)
        insert(&(p->left),key);
    else
        insert(&(p->right),key);
}
void inorder(node *head)
{
    if(head)
    {
        inorder(head->left);
        printf("%d ",head->data);
        inorder(head->right);
    }
}
int search(node *head,int key)
{
    if(head==NULL)
        return 0;
    if(head->data==key)
        return 1;
    if(head->data>key)
        search(head->left,key);
    else
        search(head->right,key);
}   

void Ipostorder(node *head)
{
    do
    {
        while(head)
        {
            if(head->right) //If right child is present
                push(head->right);  //Push right child first
            push(head);     //Push root
            head=head->left;    //Goto left
        }
        head=pop();
        if(head->right && top->data==head->right)
        {   
            pop(); //Remove right child from stack
            push(head); //Push root onto the stack
            head=head->right;

        }
        else
        {
            printf(" %d",head->data);
            head=NULL;
        }

    }while(!isEmpty());
}
void postorder(node *head)
{
    if(head)
    {
        postorder(head->left);
        postorder(head->right);
        printf(" %d",head->data);
    }
}
int main()
{
    node *head;
    int opt,choice=1,key;
    while(choice!=5)
    {
        printf("\n\nBST\n1.Insert into BST\n2.Inorder Traversal\n3.Search\n4.Iterative preorder\n5.Exit\n\nChoice - "); 
        scanf("%d",&choice);

        switch(choice)
        {
            case 1: printf("\nEnter the no of elements to be inserted - ");
                scanf("%d",&opt);
                printf("\nEnter the elements - ");          
                while(opt--)
                {           
                    scanf("%d",&key);
                    insert(&head,key);
                }
                printf("\nElement successfully inserted");
                break;
            case 2: printf("\nThe inorder traversal is  - ");
                inorder(head);
                break;
            case 3: printf("\nEnter the item to be searched - ");
                scanf("%d",&key);
                if(search(head,key))
                    printf("\nItem found");
                else 
                    printf("\nItem not found");
                break;
            case 4: printf("\nThe iterative postorder is - ");
                Ipostorder(head);
                printf("\nThe recursive postorder is - ");  
                postorder(head);

                break;
            case 5: exit(0);
                break;

        }
        getchar();
        getchar();
    }   
}

Input/Output 输入输出

BST
1.Insert into BST
2.Inorder Traversal
3.Search
4.Iterative preorder
5.Exit

Choice - 1   

Enter the no of elements to be inserted - 7

Enter the elements - 30 20 40 15 25 35 45

Element successfully inserted


BST
1.Insert into BST
2.Inorder Traversal
3.Search
4.Iterative preorder
5.Exit

Choice - 2

The inorder traversal is  - 15 20 25 30 35 40 45 


BST
1.Insert into BST
2.Inorder Traversal
3.Search
4.Iterative preorder
5.Exit

Choice - 4

Segmentation fault (core dumped)

Ipostorder dereferences top before verifying that it is not NULL. 在验证它不是NULL之前, Ipostorder取消引用top Similarly, it dereferences head after the first pop . 同样,它在第一个pop之后取消引用head

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

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