bst树的说明

 中序遍历

递归的方法

x 为指针

INORDER-TREE-WALK(x)

If(x != NULL)

   INORDER-TREE-WALK(x.left)

   print x.key

   INORDER-TREE-WALK(x.right)

非递归的方法:(将递归的实现进行翻译)

INORDER-TREE-WALK(x)

  if(x== NULL)

return

  top= x

 stack inorder

 while top != NULL or inorder 不为空

      if(top != NULL)

         inorder.push(top)

         top = top.left

     else

         top = inorder.top()

         inorder.pop()

         print(top)

         top = top.right

方法三:先调用TREE-MINMUM找到这棵树中的最小节点,再调用n – 1TREE-SUCCESSOR(利用前驱的效果是一样的

其他递归见对应的代码

 

查询二叉搜索树

 

输入一个指向树根的指针和一个关键词key,如果这个节点存在,TREE-SEARCH返回一个指向关键词为key的指针,否则返回NULL

递归算法:

TREE-SEARCH(x , key)

  Ifx == NULL or k == x.key

return x;

 if(x.key < key)

TREE-SEARCH(x.right, key)

 else

    TREE-SEARCH(x.left, key)

非递归算法:

TREE-SEARCH(x , key)

 while x != NULL and key != x.key

    if(key < x.key)

      x = x.left

    else

      x = x.right

 return x

 

得到二叉搜索树的最大值或最小值

根据定义最大值为最右侧的节点,最小值为最左侧的节点

返回一个指向给定节点x为根的子树的最小元素,不存在返回NULL

非递归

TREE-MINMUM(x)

 while x.left != NULL

    x. = x.left

 return x

递归:

TREE-MINMUM(x)

 if(x.left == NULL)

  return x

  TREE-MINMUM(x.left)

 

思路:判断有无左节点,如果没有则输出,如果有,则将其赋为左节点,循环下去

TREE-MAXMUM(x)

  while x.right != NULL

     x = x.right

  return x

二叉搜索树某个节点的后继和前驱

后继的定义:大于某个节点x的最小关键词

前驱的定义:小于某个节点x的最大关键词

可以用中序遍历来验证其的正确性

如果后继存在,返回一棵二叉搜索树中的节点x的后继,否则返回NULL

TREE-SUCCESSOR(x)

  ifx.right != NULL

  return TREE-MINMUM(x.right)

  y =x.parent

 while y != NULL and x == y.right

x = y

y = x.parent

 return y

思路:

根据后继的定义:

x节点存在右子树,则后继一定位于右子树,又由于为最小关键词,即右子树的最小节点

x节点没有右子树,只能查找其父。包含该元素的最小左子树的节点即为后继

                 O(最小左子树的节点)

                /

               O

                \

                 O

                  \

                   O(x)

TREE-PREDECESSOR(x)

   ifx.left != NULL

     return MAXMUM(x.left)

   y= x.parent

   whiley != NULL and x == y.left

    x = y

    y = x.parent

  return y

 

二叉搜索树的插入

 

该过程中将节点z作为输入,其中z,key= v ,z.left = NULL ,z.right = NULL ,将z插入到树中相应的位置

思路:从树根出发,指针x记录了一条向下的简单路径,并查找要替换的输入项zNULL

采用非递归的方法

TREE-INSERT(T,z)

   y= NULL;    //父节点

 x = T.root    //遍历指针

 while x != NULL

    y = x

    if x.key < x.key

     x = x.left

    else

     x = x.right

z.p = y

if y == NULL

  T.root = z

else if z.key < y.key

  y.left = z

else

  y.right = z;

 

二叉搜索树的删除

root为查找到的节点

一共有四种情况

1.     要删除的节点没有左右子树,即为叶子节点

      条件:root -> left == NULL , root -> right ==NULL

           此时要删除这个节点,则得判断其父辈的情况

              parent ==NULL,则证明要删除的节点root是根节点,则此时只需要将head变为空指针,即head = NULL

              否则,即parent!= NULL,则需要将parent的某一个孩子节点赋为空

利用root -> dataparent-> data的大小,判断root是位于那一边,并将父节点的那一边赋为NULL

     删除节点root

 

2.     要删除的节点有左子树,没有右子树

      条件:root -> left != NULL root-> right == NULL

          此时要删除root,则需要用左子树的根节点来代替root

            parent == NULL,则证明要删除的节点root是根节点,则此时只需要将head指向左子树的根节点即head = root –> left

            否则,即parent !=NULL

               第一步:root ->left -> parent = parent

               第二步:判断root位于parent哪一棵子树,将parent的那一棵子树赋为root -> left.

       删除节点root

 

3.     要删除的节点有右子树,没有左子树(类似于上面)

4.     要删除的节点有左右子树

     条件:root -> left!= NULL root -> right  != NULL

         此时要删除root,则需要用root的后继来代替root(由于右子树存在,实际上是取右子树的最小值)

           第一步:找到root的后继

           第二步: 判断后继的位置

                     若后继恰好是root的右子树节点,即root -> right == successor无须修改后继的parent,则只需将root的左子树赋给后继,即successor -> left = root -> left  root -> left -> parent = successor

                     否则,则需先修改后继的parent,讲后继的右子树赋给parent的左子树,即successor -> parent -> left= successor -> right successor -> right -> parent = successor -> parent,然后讲root的左右子树赋给successor(successor-> left = root -> left  root ->left -> parent = successor  successor-> right = root -> right  root-> right -> parent = successor

          第三步:successor -> parent = parent

          第四步:

parent == NULL,则证明root是根节点,则此时只需要head = successor

否则parent != NULL,判断root位于哪一棵子树,将那一棵子树赋为successor

            删除节点root

为了在二叉搜索树内移动子树,定义一个子过程TRANSPLANT,它是用另一棵子树替代一棵子树并成为其双亲的孩子节点。当TRANSPLANT用一棵以v为根的子树来替换一棵以u为根的子树时,节点u的双亲就变成v的双亲,并且最后v成为u的双亲相应的孩子

TRANSPLANTT,u,v

  if(u,parent == NULL)

    T.root = v

  else if(u == u,parent.left)

    u.parent.left = v

  else

    u,parent.right = v

  if(v != NULL)

     v,p = u.p

下面是从二叉搜索树T中删除节点z的删除过程

TREE-DELETE(T,z)

    if(z.left == NULL)

      TRANSPLANT(T,z,z.right)

    else if(z.right == NULL)

      TRANSPLANT(T,z,z.left)

    else

      y = TREE-MINMUM(z.right)   //y是没有左孩子的

      if(y.p != z)

       //y不是z的右孩子,则须将y的父辈先处理好在进行操作

         TRANSPLANT(T,y,y.right)(在这个过程中y.right.parent = y.parent,y,paret.left = y.right)

y.right = z.right

z.right.parent = y.

      TRANSPLANT(T,z,y)

//root的子树赋给后继,并修改子树的根节点

      y.left = z.left

      z.left.parent = y

delete z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值