树算法(1)
2021-04-13 15:29
标签:tno height 节点 else 使用方法 == ash delete 覆盖 容易忘的树基本操作 删除有两种方法: 插入四种情况: 删除和插入比较多时,用红黑树 树算法(1) 标签:tno height 节点 else 使用方法 == ash delete 覆盖 原文地址:https://www.cnblogs.com/mostiray/p/13340533.html以中序与任意其他方法遍历建二叉树
// 中序与后续为例
struct node {
int data;
node *l, *r;
};
// 中序的hash数组
int hashIn[MAX];
vector
BST
前驱与后继
inline node *precursor(node *root) {
node *ans = nullptr;
ans = root->l;
while (ans->r) {
ans = ans->r;
}
return ans;
}
inline node *successor(node *root) {
node *ans = nullptr;
ans = root->r;
while (ans->l) {
ans = ans->l;
}
return ans;
}
删除
z
后,根据下列两种情况进行删除
z
无孩子,直接删除。// 直接使用方法2,并在`z`左右子节点都存在时,交替使用前驱和后继
inline void transPlant(node *u, node *v) {
if (u->p->l == u)
u->p->l = v;
else
u->p->r = v;
if (v) v->p = u->p;
}
node *findNext(node *root) {
node *ans = nullptr;
if (root->l && root->r) {
static int cnt = 0;
if (cnt & 1)
ans = precursor(root);
else
ans = successor(root);
++cnt;
} else if (root->l)
ans = precursor(root);
else if (root->r)
ans = successor(root);
return ans;
}
void deleteNode(node *&root, int data) {
if (!root) return;
if (data == root->data) {
if (!root->l && !root->r) {
delete root;
root = nullptr;
} else {
node *next = findNext(root);
root->data = next->data;
if (next->l)
transPlant(next, next->l);
else
transPlant(next, next->r);
}
}
if (data data)
deleteNode(root->l, data);
else
deleteNode(root->r, data);
}
AVL 树
基本
struct node {
int data = 0, height = 1;
node *l = nullptr, *r = nullptr;
};
inline int getH(node *const root) {
if (root == nullptr) return 0;
return root->height;
}
inline int getBF(node *const root) { return getH(root->l) - getH(root->r); }
inline void updataH(node *const root) {
root->height = max(getH(root->l), getH(root->r)) + 1;
}
左右旋
void leftR(node *&root) {
if (root && root->r) {
node *tmp = root->r;
root->r = tmp->l;
updataH(root);
tmp->l = root;
updataH(tmp);
root = tmp;
}
}
void rightR(node *&root) {
if (root && root->l) {
node *tmp = root->l;
root->l = tmp->r;
updataH(root);
tmp->r = root;
updataH(tmp);
root = tmp;
}
}
插入
树型
判定条件
调整方法
LL
BF(root) == 2 && BF(root->child[0]) == 1
右旋
root
LR
BF(root) == 2 && BF(root->child[0]) == -1
左旋
root->child[0]
,右旋root
RR
BF(root) == -2 && BF(root->child[1]) == -1
左旋
root
RL
BF(root) == -2 && BF(root->child[1]) == 1
右旋
root->child[1]
,左旋root
void insertNode(node *&root, int data) {
if (root == nullptr) {
root = new node;
root->data = data;
return;
}
if (data data) {
insertNode(root->l, data);
updataH(root);
if (getBF(root) == 2) {
if (getBF(root->l) == -1) leftR(root->l);
rightR(root);
}
} else {
insertNode(root->r, data);
updataH(root);
if (getBF(root) == -2) {
if (getBF(root->r) == 1) rightR(root->r);
leftR(root);
}
}
}