二叉查找树的删除节点:
- 指针的做法:
树叶:立即删除;
只有一个节点:继承左边或者右边;
两个节点:找到右子树的最小值x,然后用x代替当前的值,最后删除右子树的最小值。
指针的做法中,上述做法只需要递归进行返回地址就好了。
- 数组做法:
方式与指针的做法相同,但是无法返回地址,所以提前记录每个节点的父节点,这样删除的时候不用向指针那样返回地址。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
struct Node
{
int val,l,r,fa;
}tree[N];
int tot;
//insert val
void Ins(int rt,int x)
{
if(x < tree[rt].val)
{
if(tree[rt].l == -1)
{
tot++;
tree[tot].fa = rt;
tree[tot].l = tree[tot].r = -1;
tree[tot].val = x;
tree[rt].l = tot;
return ;
}
else{
Ins(tree[rt].l,x);
}
}
else{
if(tree[rt].r == -1)
{
tot++;
tree[tot].fa = rt;
tree[tot].l = tree[tot].r = -1;
tree[tot].val = x;
tree[rt].r = tot;
return ;
}
else{
Ins(tree[rt].r,x);
}
}
}
//这里的初始化一定要一个根节点,这个根节点上面没有任何东西
void Init(int x)
{
tot = 1;
tree[tot].val = x;
tree[tot].fa = 0;
tree[tot].l = tree[tot].r = -1;
}
//find the min value
int find_min(int rt)
{
if(tree[rt].l == -1)
return rt;
else return find_min(tree[rt].l);
}
//find the max value
int find_max(int rt)
{
if(tree[rt].r == -1)
return rt;
else return find_max(tree[rt].r);
}
//delete the value from the tree,if the tree doesn't have the value won't delete it.
void Del(int rt,int x)
{
if(rt == -1) return ;
if(x < tree[rt].val)
{
Del(tree[rt].l,x);
}
else if(x > tree[rt].val)
{
Del(tree[rt].r,x);
}
else{
if(tree[rt].l != -1 && tree[rt].r != -1)
{
//right subtree max
int pos = find_min(tree[rt].r);
tree[rt].val = tree[pos].val;
int fa = tree[pos].fa;
//del right subtree max
if(tree[pos].val < tree[fa].val)
{
tree[fa].l = -1;
}
else{
tree[fa].r = -1;
}
}
else{
int fa = tree[rt].fa;
if(tree[rt].l == -1)//only right subtree
{
if(tree[rt].val < tree[fa].val)
{
tree[fa].l = tree[rt].r;
}
else{
tree[fa].r = tree[rt].r;
}
}
if(tree[rt].r == -1)//only left subtree
{
if(tree[rt].val < tree[fa].val)
{
tree[fa].l = tree[rt].l;
}
else{
tree[fa].r = tree[rt].l;
}
}
}
}
}
void dfs(int rt)
{
if(tree[rt].l != -1) dfs(tree[rt].l);
printf("%d ",tree[rt].val);
if(tree[rt].r != -1) dfs(tree[rt].r);
}
int main(void)
{
Init(6);
for(int i=1;i<=9;i++)
if(i!=6){
Ins(1,i);
}
dfs(1);
printf("\n");
Del(1,3);
dfs(1);
return 0;
}