【发布时间】:2021-03-15 00:27:50
【问题描述】:
我的 BST 定义如下:
typedef struct trnode {
Item item;
struct trnode *left;
struct trnode *right;
} Trnode;
typedef struct tree {
Trnode *root;
size_t size;
} Tree;
我经常遇到的问题是我想知道特定树节点的父节点是什么。定义一个包含父节点的树节点是否很常见,例如:
typedef struct trnode {
Item item;
struct trnode *parent;
struct trnode *left;
struct trnode *right;
} Trnode;
或者包含了不应该做的事情,如果是这样:为什么不呢?
更新:有人要求查看我的删除代码。这是未经测试的,对我来说很难写(我是 C 的初学者,也只是学习 BST 数据结构)。无论如何,这里是:
Node * SeekInsertionParent(const Node *root, const Node *pnode)
{
// cmp returns -1 (less than), +1 (greater than), or 0 (equal)
int cmp = CmpNodes(pnode, root);
if (cmp == 0) return NULL; // ignore this for now
Node *child = (cmp < 0)? root->left : root->right;
if (child == NULL)
return root;
else
SeekInsertionParent(child, pnode);
}
Bool DeleteItem(Tree *ptree, const Item *pi)
{
Node *parent;
Node *node = SeekItem(pi, ptree);
if (node == NULL)
return false;
// (1) if no children, then it's a leaf, just delete it
if (!node->left && !node->right) {
free(node);
return true;
}
// (2) if it has one child, link that child to the parent then free the node
if (!node->left || !node->right) {
Node *descendant = (node->left)? node->left : node->right;
descendant->parent = parent;
if (parent->left == node)
parent->left = descendant;
else
parent->right = descendant;
free(node);
}
// (3) if it has two children, then:
// (a) attach the child same-side child to the parent node;
// (b) using the root of the attachment, find the place to insert the other-side child
else {
Node *insert_at, *other_side;
if (parent->left == node) {
node->left->parent = parent;
parent->left = node->left;
other_side = node->right;
} else {
node->right->parent = parent;
parent->right = node->right;
other_side = node->left;
}
free(node);
insert_at = SeekInsertionParent(parent, other_node);
if (insert_at->left == NULL) {
insert_at->left=node;
node->parent=insert_at;
} else {
insert_at->right=node;
node->parent=insert_at;
}
}
return true;
}
【问题讨论】:
-
您可能想阅读我之前问过的stackoverflow.com/questions/41421881/…。
-
不存储父指针。维护它需要大量工作,而且很少值得。 [另外:根节点的括号指针应该是什么?]
-
不要这样做,因为你会导致 O(n) 内存过剩。
-
@carl.hiass 指针占用了保存地址所需的空间,在 32 位机器上为 4 个字节,在 64 位机器上为 8 个字节。这意味着如果添加父指针,在 32 位机器上将有 4*n 字节的内存盈余,在 64 位机器上将有 8*n 字节的内存盈余。
标签: c binary-search-tree