二叉搜索树
二叉搜索树:左子树 < 根节点 < 右子树。且不能出现相同的val。
树的初始化
用数组模拟二叉树
const int maxn = 500050;
struct hzw
{
int lc,rc,val;
}a[maxn];
int cur,root;
二叉查找树的初始化
const int INF = 0x3f3f3f3f<<1;
int New(int val)
{
a[++cur].val = val;
return cur;
}
void Build()
{
New(-INF), New(INF);
root = 1, a[1].rc = 2;
}
为了避免越界,减少边界情况的特殊判断,编程实现时一般在 树中额外插入一个val为正无穷和负无穷的节点。 仅由这两个节点构成的B二叉搜索树就是一棵初始的空BST。如果要遍历二叉搜索树时,只需要跳过输出val为INF和-INF的点即可。
二叉查找树的插入
void Insert(int &p, int val)
{
if (p == 0)
{
p = New(val);
return;
}
if (val == a[p].val) return;
if (val < a[p].val) Insert(a[p].lc, val);
else Insert(a[p].rc, val);
}
我们通过插入操作来生成一棵二叉查找树。函数中的参数p为根节点的编号,每次插入时都从根节点开始。
二叉搜索树的查找
在BST中检索是否存在值为val的节点。 设变量p等于根节点root,执行以下过程:
1.若p的值等于val,则已经找到
2.若p的值大于val
(1) 若p的左儿子为空,则说明不存在val
(2)若p的左儿子不空,在p的左子树中递归进行检索
3.若p的值小于val
(1) 若p的右子节点为空,则说明不存在val
(2) 若p的右子节点不空,在p的右子树中递归进行检索
int Find(int p, int val)
{
if(p == 0) return 0;
if(val == a[p].val) return p;
if(val < a[p].val) return Find(a[p].lc, val);
else return Find(a[p].rc, val);
}
二叉搜索树的删除
二叉树的删除操作,首先需要二叉树查找后继。
二叉搜索树的后继
二叉树的后继是指,在二叉树中找到大于某一点val的最小节点。
初始化ans为正无穷节点的编号(编号为2)。然后,从根节点开始在BST中检索val。在检索的过程中,每经过一个节点,都检查该节点的值,判断能否更新所求的后继val。 检索完成后,有三种可能的结果:
1.没有找到val,此时val的后继就在已经经过的节点中,val即为所求。
2.找到了值为val的节点p,但p没有右子树与上一种情况相同,val即为所求
3.找到了值为val的节点p,且p有右子树从p的右子节点出发,一直向左走,就找到了val的后继
int GetNext(int val)
{
int ans = 2;
int p = root;
while(p)
{
if (val == a[p].val)
{
if(a[p].rc > 0)
{
p = a[p].rc;
while(a[p].lc > 0) p = a[p].lc;
ans = p;
}
break;
}
if(a[p].val > val && a[p].val < a[ans].val) ans = p;
p = val < a[p].val ? a[p].lc : a[p].rc;
}
return a[ans].val;
}
删除
|