【发布时间】:2016-01-28 00:42:09
【问题描述】:
我正在学习如何使用后序遍历来删除二叉树。我知道要删除一个节点,首先我们需要删除它的子节点,然后是节点本身,所以后序遍历最适合删除二叉树。我想用中序遍历做同样的事情,一切正常,但我不明白下面的代码是如何工作的?
#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。
我不明白这一切是如何运作的。如果我错了,请纠正我。
【问题讨论】:
-
该代码非常适合遍历(即读取)树,但删除时要小心 - 您有“free(root)”后跟“delete_tree(root->right);”,所以您在删除“root”后访问“root->right”。
-
如果不删除右子树,您希望
delete_tree(root->right)做什么? -
我同意你们所说的,但我想问的是,一旦
2被释放,它应该丢失所有数据,这意味着它也应该丢失指向右孩子的指针同样是5,但即使在释放2之后仍然可以访问5,如何?
标签: c data-structures tree binary-tree