1.什么是搜索二叉树
搜索二叉树遵循 左《 中《右 节点的原则
2.搜索二叉树构建
递归构建
void insertNode(p,z)
{
if(p== null)
{
p = z;
p.left = p.right =null;
p.p = null;
return;
}
if(z.key < p.key)
{
if(p.left != null){
insertNode(p.left,z);
}
else
{
p.left = z;
z.p =p;
}
}
非递归构建
void insertNode(root,z)
{
y = null;
x = root;
while(x ! =null)
{
y = x;
if(z.key < y.key)
{
x =x.left;
}
else
x =x.right;
}
z.p =y;//父节点
if(y == null)
{
root = x;
}
else if(z.key < y.key)
{
y.left = z;
}
else if(z.key >= y.key)
{
y.right = z;
}
}
3.搜索二叉树查找
node* searchNode(p,z)
{
x = p;
while(x != null&&x !=z.key)
{
if(z.key < x.key) x = x.left;
else x =x.right;
}
return x;
}
4.搜索二叉树删除节点
/*在来看删除节点,删除节点可能会用到 后继的概念(只有有两个孩子的情况才用到)。
后继节点是什么呢,因为搜索二叉树必须是中序排列好的呀(左《中《右),所以中序是从小到大有序,为了保持这种有序就需要在用后继(用前驱也可)节点替换当前节点保证顺序。
删除有四种情况,
没有子节点直接删除就ok了
如果左孩子为空且右孩子不空,直接将孩子节点提到删除点z
如果右孩子为空且左孩子不空,直接将孩子节点提到删除点z
如果有两个子节点,那么寻找后继来替换掉删除点z,同时需要处理好后继y的右子树
*/
因为在删除中多处用到了节点替换,先写个独立方法,这里T 指向一棵树
void translateNode(T,z,y)
{
if (z == null ) return;
if (z.p != null )
{
T.root = y;
}
else if(z.p.left ==z)
{
z.p.left = y;
}
else if(z.p.right == z)
{
z.p.ritht = y;
}
if (y!=null)
y.p = z.p;
}
void deleteNode(T,z)
{
if(z.left ==null&&z.right==null)
{
if(z.p.left = z) z.p.left = null;
else z.p.right = null;
}
else if(z.left = null)
{
translateNode(T,z,z.right);
}
else if(z.right = null)
{
translateNode(T,z,z.left);
}
else
{
y = tree_minNode(z.right);
if(y.p != z)
{
translateNode(T,y,y.right);
y.right = z.right;
y.right,p =y;
}
translateNode(T,z,y);
y.left =z.left;
y.left.p =y;
}
}
补充:查找搜索二叉树某个节点的后继节(中序遍历顺序)
1.有右子树则肯定在右子树中
2.如果没有右子树则在有左子树的最底层祖先节点
(2 的意思 从该点向上找,只要找到该节点所在子树是某节点的左子树就ok)
node* findNext(z)
{
x = null;
if(z.right != null)
{
return findMinNode(z.right);
}
x = z.p;//向顶层方向伴随指针
while(x !=null&& x.right == z ) //找到该子树作为left才能停止
{
z = x;
x = x.p;
}
return y;
}