前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构与算法(九)二叉搜索树的删除操作

数据结构与算法(九)二叉搜索树的删除操作

作者头像
老沙
发布2019-10-15 16:58:07
8690
发布2019-10-15 16:58:07
举报
文章被收录于专栏:老沙课堂

1、二叉搜索树的删除操作

介绍

关于二叉搜索树的删除操作,先弄清如何找到前驱节点和后继节点

前驱节点(predecessor)

介绍

•前驱节点:中序遍历时的前一个节点•如果左子树存在,从该节点的左子节点的最右的节点。•如果左子树 == null && 父节点!= null 父节点为父节点遍历,一直到节点关系发生改变。如下图所示。•如果左子树 == null && 父节点== null ,没有前驱节点。

代码
代码语言:javascript
复制
public Node<E> findPredecessorNode(E element) {
  return findPredecessorNode(node(element));
}

private Node<E> findPredecessorNode(Node<E> element) {
  if (element.left != null) {
    Node<E> node = element.left;
    while (node.right!= null) {
      node = node.right;
    }
    return node;
  }

  while (element.parent != null && element == element.parent.left) {
    element = element.parent;
  }
  return element.parent;
}

后继节点(succeessor)

•前驱节点:中序遍历时的后一个节点•如果右子树存在,从该节点的左子节点的最左的节点。•如果右子树 == null && 父节点!= null 父节点为父节点遍历,一直到节点关系发生改变。•如果右子树 == null && 父节点== null ,没有后继节点。

删除节点

叶子节点

•直接删除

度为1的节点

•用子节点替换既可

度为2的节点

•找到前驱或者后继节点的值,并替换原节点。•他的前驱、后继节点的度只可能是0或者是1。

代码语言:javascript
复制
private void remove(Node<E> node) {
  if (node == null) return;
  size--;

  // 度为2的节点
  if (node.twoChildren()) { 
    // 找到后继节点
    Node<E> s = findSucceessorNode(node);
    // 用后继节点的值覆盖原节点的值
    node.element = s.element;

    node = s;
  }

  // 删除的node节点  (node的度必然是1或者0) 如果是0 replacement为null
  Node<E> replacement = node.left != null ? node.left : node.right;

  // 度为1
  if (replacement != null) {
    // 更改parent
    replacement.parent = node.parent;
    // 更改parent的 chil
    if (node.parent == null) { // node是度为1的节点并且是根节点
      root = replacement;
    } else if (node == node.parent.left) {
      node.parent.left = replacement;
    } else { // node == node.parent.right
      node.parent.right = replacement;
    }
  } else if (node.parent == null) { // node是叶子节点并且是根节点
    root = null;
  } else { // node是叶子节点
    if (node == node.parent.left) {
      node.parent.left = null;
    } else { 
      node.parent.right = null;
    }
  }
}

2、根据遍历结果重构二叉树

•中序遍历+ 前/后序遍历 •可以确定一颗唯一二叉树•前序遍历+ 后序遍历•如果他是一颗真二叉树(Proper Binary Tree) ,结果是唯一的。•其他情况 不唯一。

代码语言:javascript
复制
List<Integer> perorder = Arrays.asList(5,1,2,4,3,9);
List<Integer> inorder = Arrays.asList(2,1,4,5,9,3);


private  Node<E> RefactoringTree(List<E> perorderList, List<E> inorderList) {
  if (perorderList.size() == 0|| inorderList.size() == 0) {
    return null;
  }
  E element = perorderList.get(0);

  Node<E> root = new Node<>(element, null);
  perorderList = perorderList.subList(1, perorderList.size());
  int index = inorderList.indexOf(element);
  List<E> leftInorderList = inorderList.subList(0, index);
  List<E> rightInorderList = inorderList.subList(index + 1, inorderList.size());

  List<E> leftperOrderList = perorderList.subList(0, leftInorderList.size());
  List<E> rightperOrderList = perorderList.subList(leftperOrderList.size(), perorderList.size());

  root.left = RefactoringTree(leftperOrderList, leftInorderList);
  root.right = RefactoringTree(rightperOrderList, rightInorderList);
  return  root;
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老沙说点事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、二叉搜索树的删除操作
    • 介绍
      • 前驱节点(predecessor)
        • 后继节点(succeessor)
          • 删除节点
          • 2、根据遍历结果重构二叉树
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档