数据结构与算法(十三)删除二叉树结点

来源:互联网 发布:汽车网络销售 编辑:程序博客网 时间:2024/04/29 21:38

删除二叉树结点


删除结点是二叉树操作中最复杂的。在删除之前首先要查找要删除的结点。找到结点后,这个要删除的结点可能会有三种情况需要考虑。


1. 该节点是叶子结点,没有子结点

要删除叶子结点,只需要改变该节点的父结点的引用值,将指向该节点的引用值设置为null就可以了。


2. 该节点有一个子结点

改变父结点的引用,将其直接指向要删除结点的子结点。


3. 该节点有两个子结点

要删除有两个子结点的结点,就需要使用它的中序后继来替代该节点。


二叉树结点

/* * 二叉树结点 */public class Node {//数据项public long data;public String sData;//左子结点public Node leftChild;//右子结点public Node rightChild;/* * 构造函数 */public Node(long data,String sData){this.data=data;this.sData=sData;}}

二叉树类

* 二叉树类 *//* * 为什么要使用树 *  * 有序数组插入数据项和删除数据项太慢 * 链表查找数据太慢 * 在树中能非常快速的查找数据项、删除数据项和插入数据项 */public class Tree {//根结点public Node root;/* * 插入结点 */public void insert(long value,String sValue){//封装结点Node newNode=new Node(value,sValue);//引用当前结点Node current=root;//引用父结点Node parent;//如果root为null,也就是第一插入的时候if(root==null){root=newNode;return;}else{while(true){//父结点指向当前结点parent=current;//如果当前指向的结点数据比插入的要大,则向左走if(current.data>value){current=current.leftChild;if(current==null){parent.leftChild=newNode;return;}}else{current=current.rightChild;if(current==null){parent.rightChild=newNode;return;}}}}}/* * 查找结点 */public Node find(long value){//引用当前结点,从跟结点开始Node current=root;//循环,只要查找值不等于当前结点的数据项while(current.data!=value){//进行比较,比较查找值和当前结点的大小if(current.data>value){current=current.leftChild;}else{current=current.rightChild;}//如果找不到if(current==null){return null;}}return current;}/* * 删除结点 *  * 1 该节点是叶子节点,没有子节点 * 要删除叶结点,只需要改变该节点的父结点的引用值,将指向该节点的引用设置为null就可以了 *  * 2 该节点有一个子节点 * 改变父结点的引用,将其直接指向要删除结点的子节点 *  * 3 该节点有两个子节点 * 要删除有两个子节点的结点,就需要使用它的中序后继来代替该节点 * */public boolean delete(long value){//引用当前结点,从根节点开始Node current=root;//引用当前结点的父结点Node parent=root;//是否为左结点boolean isLeftChild=true;while(current.data!=value){parent=current;//进行比较,比较查找值和当前结点的大小if(current.data>value){current=current.leftChild;isLeftChild=true;}else{current=current.rightChild;isLeftChild=false;}//如果找不到if(current==null){return false;}}//删除叶子结点,也即该节点没有子结点if(current.leftChild==null&¤t.rightChild==null){if(current==root){root=null;}//如果它是父结点的左子结点else if(isLeftChild){parent.leftChild=null;}else{parent.rightChild=null;}}else if(current.rightChild==null){if(current==root){root=current.leftChild;}else if(isLeftChild){parent.leftChild=current.leftChild;}else{parent.rightChild=current.leftChild;}}else if(current.leftChild==null){if(current==root){root=current.rightChild;}else if(isLeftChild){parent.leftChild=current.rightChild;}else{parent.rightChild=current.rightChild;}}else{Node successor=getSuccessor(current);if(current==root){root=successor;}else if(isLeftChild){parent.leftChild=successor;}else{parent.rightChild=successor;}successor.leftChild=current.leftChild;    }return true;}public Node getSuccessor(Node delNode){Node successor=delNode;Node successorParent=delNode;Node current=delNode.rightChild;while(current!=null){successorParent=successor;successor=current;current=current.leftChild;}if(successor!=delNode.rightChild){successorParent.leftChild=successor.rightChild;successor.rightChild=delNode.rightChild;}return successor;}/* * 前序遍历 */public void frontOrder(Node localNode){if(localNode!=null){//访问根结点System.out.println(localNode.data+","+localNode.sData);//前序遍历左子树frontOrder(localNode.leftChild);//前序遍历右子树frontOrder(localNode.rightChild);}}/* * 中序遍历 */public void inOrder(Node localNode){if(localNode!=null){//中序遍历左子树inOrder(localNode.leftChild);//访问根结点System.out.println(localNode.data+","+localNode.sData);//中序遍历右子树inOrder(localNode.rightChild);}}/* * 后序遍历 */public void afterOrder(Node localNode){if(localNode!=null){//后序遍历左子树afterOrder(localNode.leftChild);//后序遍历右子树afterOrder(localNode.rightChild);//访问根结点System.out.println(localNode.data+","+localNode.sData);}}}

测试:

public class TestTree {public static void main(String[] args) {// TODO Auto-generated method stubTree tree=new Tree();tree.insert(10,"James");tree.insert(20,"Yao");tree.insert(15,"Kobi");tree.insert(3,"Mac");tree.insert(4,"Zhangsan");tree.insert(90, "Lisi");//System.out.println(tree.root.data);//System.out.println(tree.root.rightChild.data);//System.out.println(tree.root.rightChild.leftChild.data);//System.out.println(tree.root.leftChild.data);////Node node =tree.find(3);//System.out.println(node.data+","+node.sData);//前、中、后序遍历//tree.frontOrder(tree.root);//tree.inOrder(tree.root);//tree.afterOrder(tree.root);//删除叶子结点tree.delete(10);tree.inOrder(tree.root);}}




0 0