后序树遍历中的分段错误

时间:2015-02-17 19:31:23

标签: c tree segmentation-fault binary-search-tree tree-traversal

我尝试使用单个堆栈实现树的后序遍历。 我现在遇到了细分错误 有人可以解释一下原因吗? Image Here

这是算法:

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.

示例

。正确的孩子1存在。    按3进行堆叠。按1进行堆叠。搬到左边的孩子。         堆栈:3,1

  1. 存在2的右孩子。 按5进行堆叠。按2进行堆叠。搬到左边的孩子。     堆栈:3,1,5,2

  2. 4的正确孩子不存在。 ' 按4进行堆叠。搬到左边的孩子。     堆栈:3,1,5,2,4

  3. 当前节点为NULL。 从堆栈弹出4。 4的正确孩子不存在。 打印4.将当前节点设置为NULL。     堆栈:3,1,5,2

  4. 当前节点为NULL。 从堆栈弹出2。由于2的右子等于叠顶元素, 从堆栈弹出5。现在按2来叠加。
    将当前节点移动到2的右子节点,即5     堆栈:3,1,2

  5. 5的正确孩子不存在。按5进行堆叠。搬到左边的孩子。     堆栈:3,1,2,5

  6. 当前节点为NULL。从堆栈弹出5。 5的正确孩子不存在。 打印5.将当前节点设置为NULL。     堆栈:3,1,2

  7. 当前节点为NULL。从堆栈弹出2。 2的右子不等于叠顶元素。 打印2.将当前节点设置为NULL。     堆栈:3,1

  8. 当前节点为NULL。从堆栈弹出1。 由于1的右子级等于堆栈顶部元素,因此从堆栈弹出3。 现在按1进行堆叠。将当前节点移动到1的右子节点,即3     堆栈:1

  9. 重复上述步骤并打印6,7和3。 弹出1和打印1.

  10. 代码:问题在于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();
        }   
    }
    

    输入/输出

    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)
    

1 个答案:

答案 0 :(得分:1)

Ipostorder在验证它不是NULL之前解除引用top。同样,它会在第一个head之后取消引用pop