扩展树是一种自平衡二进制搜索树,具有最近访问的元素可以快速再次访问的附加属性。它以O(log n)摊销时间执行基本操作,例如插入,查找和删除。对于许多非随机操作序列,即使序列的具体模式未知,八叉树的性能也比其他搜索树好。
我在splay树中的remove方法有一些问题。谁能帮我吗?
struct Node {
int key;
string value;
Node* parent;
Node* left;
Node* right;
Node(int key,const string& value) {
this->key = key;
this->parent = nullptr;
this->left = nullptr;
this->right = nullptr;
this->value = value;
}
};
void SplayTree::zig(Node *node) {
Node *p = node->parent;
node->parent = nullptr;
p->parent = node;
Node *c = nullptr;
if (p->left == node) {
c = node->right;
node->right = p;
p->left = c;
} else {
c = node->left;
node->left = p;
p->right = c;
}
if (c != nullptr) {
c->parent = p;
}
}
void SplayTree::zigZig(Node *node) {
Node *p = node->parent;
Node *pp = p->parent;
node->parent = pp->parent;
p->parent = node;
if (p->left == node) {
Node *c = node->right;
Node *pc = p->right;
node->right = p;
p->left = c;
p->right = pp;
pp->parent = p;
pp->left = pc;
if (node->parent != nullptr) {
if (node->parent->left == pp)
node->parent->left = node;
else
node->parent->right = node;
}
if (c != nullptr)
c->parent = p;
if (pc != nullptr)
pc->parent = pp;
}
else {
Node *c = p->left;
Node *pc = node->left;
node->left = p;
p->left = pp;
p->right = pc;
pp->parent = p;
pp->right = c;
if (node->parent != nullptr) {
if (node->parent->left == pp)
node->parent->left = node;
else
node->parent->right = node;
}
if (c != nullptr)
c->parent = pp;
if (pc != nullptr)
pc->parent = p;
}
}
void SplayTree::zigZag(Node *node) {
Node *p = node->parent;
Node *pp = p->parent;
Node *cl = node->left;
Node *cr = node->right;
node->parent = pp->parent;
p->parent = node;
pp->parent = node;
if (p->right == node) {
node->left = p;
node->right = pp;
p->right = cl;
pp->left = cr;
if (cl != nullptr)
cl->parent = p;
if (cr != nullptr)
cr->parent = pp;
} else {
node->left = pp;
node->right = p;
p->left = cr;
pp->right = cl;
if (cl != nullptr)
cl->parent = pp;
if (cr != nullptr)
cr->parent = p;
}
if (node->parent != nullptr) {
if (node->parent->left == pp)
node->parent->left = node;
else
node->parent->right = node;
}
}
void SplayTree::splay(Node *node) {
while (node->parent != nullptr) {
Node *p = node->parent;
Node *pp = p->parent;
if (pp == nullptr)
zig(node);
else if ((pp->left == p && p->left == node) || (pp->right == p && p->right == node))
zigZig(node);
else
zigZag(node);
}
this->root = node;
}
SplayTree::SplayTree() {
this->root = nullptr;
}
Node* SplayTree::find(int key) {
Node *res = nullptr;
Node *cur = this->root;
Node *prev = nullptr;
while (cur != nullptr) {
prev = cur;
if (key < cur->key)
cur = cur->left;
else if (key > cur->key)
cur = cur->right;
else {
res = cur;
break;
}
}
if (res != nullptr)
splay(res);
else if (prev != nullptr)
splay(prev);
return res;
}
void SplayTree::insert(int key,const string& value) {
if (root == nullptr) {
root = new Node(key,value);
return;
}
Node *cur = this->root;
while (cur != nullptr) {
if (key < cur->key) {
if (cur->left == nullptr) {
Node *node = new Node(key,value);
cur->left = node;
node->parent = cur;
splay(node);
return;
}
else
cur = cur->left;
}
else if (key > cur->key) {
if (cur->right == nullptr) {
Node *node = new Node(key,value);
cur->right = node;
node->parent = cur;
splay(node);
return;
}
else
cur = cur->right;
} else {
splay(cur);
return;
}
}
}
void SplayTree::remove(int key) {
Node *n = find(key);
if (n == nullptr) {
return;
}
Node *l = n->left;
Node *r = n->right;
if (l == nullptr && r == nullptr) {
this->root = nullptr;
} else if (l == nullptr) {
Node *k = r;
while (k->left != nullptr)
k = k->left;
splay(k);
} else {
Node *k = l;
while (k->right != nullptr)
k = k->right;
splay(k);
if (r != nullptr) {
k->right = r;
r->parent = k;
}
}
delete n;
}
当我添加键1和2时,我正在尝试删除带有1的节点。代码无法正常工作,因为带有键1的节点没有删除;