繁体   English   中英

使用顺序遍历删除二叉树

[英]Deleting a binary tree using inorder traversal

我正在学习如何使用Postorder遍历删除二叉树。 我了解要删除一个节点,首先需要删除其子节点,然后再删除节点本身,因此Postorder遍历是删除二叉树的最佳选择。 我想过使用顺序遍历做同样的事情,一切正常,但我不明白下面的代码如何工作?

#include<stdio.h>
#include<malloc.h>

struct b_tree{
    int data;
    struct b_tree *left,*right;
};

typedef struct b_tree tree;

tree* create_node(int data)
{
    struct b_tree* new_node=(tree*)malloc(sizeof(tree));
    new_node->data=data;
    new_node->left=NULL;
    new_node->right=NULL;
    return new_node;
}

void delete_tree(tree *root)
{
    if(root==NULL)
        return;
    delete_tree(root->left);
    printf("Deleting %d node.\n",root->data);
    free(root);
    delete_tree(root->right);
}

int main()
{
    tree *root=NULL;
    root=create_node(1);
    root->left=create_node(2);
    root->right=create_node(3);
    root->left->left=create_node(4);
    root->left->right=create_node(5);
    root->left->right->left=create_node(6);
    root->left->right->right=create_node(7);
    root->right->right=create_node(8);
    root->right->right->left=create_node(9);
    delete_tree(root);
    root=NULL;
    return 0;
}

树
根据要遍历的顺序遍历,要删除的第一个节点是4 ,然后是2 ,但是一旦释放2它就应该释放所有数据,这意味着它也不应保留指向右节点的指针5 ,即使释放了2它的左子节点5仍被遍历,但由于节点2已被释放,因此不应发生。

上面代码的输出是:
产量

我期望输出按照以下节点顺序: 4 2 1

我不明白这一切如何运作。 如果我错了,请纠正我。

它显示的输出是正确的,因为首先要先遍历left sub-tree然后遍历rootright sub-tree

您不会得到4 2 1因为4是左边的子树,然后它到达root2 ,然后到右边的子树2

当它太右子树的根成为5和它的左子树为6 。然后5 ,然后到右子树57

1是根,因此如果不遍历左子树,它将不会变为1

要遍历Inorder中的二叉树,请执行以下操作

(i) Traverse the left most subtree starting at the left external node, 
(ii) Visit the root, and 
(iii) Traverse the right subtree starting at the left external node.

现在要删除节点,

(i) Traverse the left most subtree starting at the left external node,
(ii) delete the root, and 
(iii) Traverse the right subtree starting at the left external node.
void delete_tree(tree *root)
{
    if(root==NULL)
        return;
    delete_tree(root->left);
    printf("Deleting %d node.\n",root->data);
    free(root);
    delete_tree(root->right);
}

这是一个有序遍历,其中指针将首先指向最左边的节点,然后是根节点,然后是最右边的节点。 由于4是最左边的节点,因此已被打印,然后遍历到2。 在此之后,最右边的节点是5。因为5有两个附加节点。 它将再次迭代到最左边的节点6。因此将其打印为4,2,6,5,7,3,9,8

我最初将其发布为评论,但似乎询问该问题的人对我的回答感到满意,因此我将在此处更详细地发布它。

拨打免费电话时,请务必准确说明免费电话实际上会做什么,否则可能会发生这种情况。

C库函数void free(void * ptr)取消分配先前由对calloc,malloc或realloc的调用分配的内存。

请注意,free函数不会更改指针的值,它只是将内存返回给OS,以便可以将其分配给另一个程序。 因此,人们通常在调用free之后“清除”指针以避免访问另一个程序已更改的内存。

root = VOID;

上面的代码在释放根节点后并没有清除它,因为内存仍然在那里。 这样,C代码便可以转到该存储位置(操作系统已经接收到)并对其进行修改。 这是极端危险的行为,因为OS可以将此内存分配给另一个程序,然后您的程序可能会更改,从而导致明显的意外行为。 一个简单的解决方法是在释放根节点之前删除正确的节点。

暂无
暂无

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

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