JAVA实现二叉树的基本操作

来源:互联网 发布:linux启动u盘制作工具 编辑:程序博客网 时间:2024/05/01 10:01

Node类:

// 二叉树节点  public class Node {        // 数据      public Long data;        // 左子节点      public Node leftChild;        // 右子节点      public Node rightChild;        public Node(long data) {          this.data = data;      }  }  


二叉树的插入、查找、遍历较为容易,删除节点较为麻烦点。

要删除的节点可分成3种情况去处理:  (1) 该节点没有子节点:直接删除该节点即可;  (2) 该节点只有一个节点,左子节点或者右子节点:只需将其父节点的左/右子节点的引用指向其子节点即可;  (3) 该节点有两个子节点:需要将该节点的右子树中最小的节点替换到该节点即可。

Tree类:

public class Tree {    // 根节点    private Node root;    /**     * 插入节点     * @param value     */    public void insert(long value) {        // 创建新节点        Node newNode = new Node(value);        Node current = root;        // 如果root为null,则树为空        if(root == null) {            root = newNode;        } else {            while (true) {                // 如果当前节点数据比value要小,则向左;否则向右                if(current.data > value) {                    if(current.leftChild == null) {                        current.leftChild = newNode;                        return;                    } else {                        current = current.leftChild;                    }                } else {                    if(current.rightChild == null) {                        current.rightChild = newNode;                        return;                    } else {                        current = current.rightChild;                    }                }            }        }    }    /**     * 删除节点     * @param value     */    public boolean delete(long value){        // 当前节点        Node current = root;        // 父节点        Node parent = current;        // 标记要删除的节点,是其父节点的左子节点还是右子节点        boolean isLeftChild = true;        // 查找要删除的节点        while (current.data != value) {            parent = current;            if(current.data > value) {                current = current.leftChild;                isLeftChild = true;            } else if(current.data < value) {                current = current.rightChild;                isLeftChild = false;            }            // 如果查找不到            if(current == null)                return false;        }        /*           要删除的节点有3种情况:             (1) 该节点没有子节点;             (2) 该节点只有一个节点,左子节点或者右子节点;             (3) 该节点有两个子节点。(这种较为复杂)          */        if(current.leftChild == null && current.rightChild == null) {  // 该节点没有子节点;            if(current == root) {                root = null;            }            if(isLeftChild) {                parent.leftChild = null;            } else {                parent.rightChild = null;            }        } else if(current.rightChild == null) {    // 该节点只有一个左子节点;            if(current == root) {                root = current.leftChild;            }            if(isLeftChild) {                parent.leftChild = current.leftChild;            } else {                parent.rightChild = current.leftChild;            }        }  else if(current.leftChild == null) {    // 该节点只有一个右子节点;            if(current == root) {                root = current.rightChild;            }            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;    }    // 拿到中序后继的节点,也就是当前节点的右子树中数值最小的那个节点    private 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 list(){        inOrderTraverse(root);    }    private void inOrderTraverse(Node node) {        if (node == null)            return;        inOrderTraverse(node.leftChild);        System.out.print(node.data + " ");        inOrderTraverse(node.rightChild);    }    /**     * 查找节点     * @param value     */    public Node find(long value){        if(root == null)            return null;        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;    }}


测试类:

public class Test {    public static void main(String[] args) {        Tree tree = new Tree();        int[] arr = new int[]{5,3,4,1,12,15,9,8,6,7,10,13,14,30};        for (int i = 0; i < arr.length; i++) {            tree.insert(arr[i]);        }        tree.list();        System.out.println();        System.out.println(tree.delete(12));        tree.list();    }}



1 0