简体   繁体   中英

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. Push 3 to stack. Push 1 to stack. Move to left child. Stack: 3, 1

  1. Right child of 2 exists. Push 5 to stack. Push 2 to stack. Move to left child. Stack: 3, 1, 5, 2

  2. Right child of 4 doesn't exist. ' Push 4 to stack. Move to left child. Stack: 3, 1, 5, 2, 4

  3. Current node is NULL. Pop 4 from stack. Right child of 4 doesn't exist. Print 4. Set current node to NULL. Stack: 3, 1, 5, 2

  4. Current node is NULL. Pop 2 from stack. Since right child of 2 equals stack top element, pop 5 from stack. Now push 2 to stack.
    Move current node to right child of 2 ie 5 Stack: 3, 1, 2

  5. Right child of 5 doesn't exist. Push 5 to stack. Move to left child. Stack: 3, 1, 2, 5

  6. Current node is NULL. Pop 5 from stack. Right child of 5 doesn't exist. Print 5. Set current node to NULL. Stack: 3, 1, 2

  7. Current node is NULL. Pop 2 from stack. Right child of 2 is not equal to stack top element. Print 2. Set current node to NULL. Stack: 3, 1

  8. Current node is NULL. Pop 1 from stack. Since right child of 1 equals stack top element, pop 3 from stack. Now push 1 to stack. Move current node to right child of 1 ie 3 Stack: 1

  9. Repeat the same as above steps and Print 6, 7 and 3. Pop 1 and Print 1.

Code : Problem lies in Ipostorder function ..if you comment and run you won't get a segmentation fault.

#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. Similarly, it dereferences head after the first pop .

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.

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