Java实现二叉排序树的插入查询与遍历

二叉排序树的非递归插入,非递归查询,寻找最大值,寻找最小值java

package whut.tree;
//二叉排序树的非递归插入,非递归查询,寻找最大值,寻找最小值
class Node {
    private int data;
    private Node left;
    private Node right;
    public Node(int data) {
        this.data = data;
    }
    public int getData() {
        return data;
    }
    public Node getLeft() {
        return left;
    }
    public void setLeft(Node left) {
        this.left = left;
    }
    public Node getRight() {
        return right;
    }
    public void setRight(Node right) {
        this.right = right;
    }
    // 展现节点数据
    public void displayNode() {
        System.out.println(" " + data + " ");
    }
}
// 树
public class BinaryTree {
    private Node root;// 树根
    // 非递归方式插入新的节点数据,
    public void insert(int data) {
        Node newNode = new Node(data);
        if (root == null) {
            root = newNode;
        } else {
            // 子节点,当前节点
            Node current = root;
            // 父节点
            Node parent;
            while (true)// 寻找插入的位置
            {
                parent = current;
                // 当小于根节点,插入到左边
                if (data < current.getData()) {
                    current = current.getLeft();
                    // 跳出循环
                    if (current == null) {
                        parent.setLeft(newNode);
                        return;
                    }
                } else {
                    current = current.getRight();
                    if (current == null) {
                        parent.setRight(newNode);
                        return;
                    }
                }
            }
        }
    }
    // 非递归方式实现查询
    public Node find(int data) {
        Node current = root;
        while (current.getData() != data) {
            if (current.getData() < data)
                current = current.getLeft();
            else
                current = current.getRight();
            // 当一个元素不在一个二叉树中,确定为null了
            if (current == null)
                return null;
        }
        // 跳出循环说明找到了那个相等的
        return current;
    }
    // 找二叉树最小的节点,一直遍历左孩子,直到其左孩子为null
    public Node findMinNode() {
        Node current;
        Node parent;
        //
        if (root == null) {
            return null;
        } else {
            parent = root;
            current = parent.getLeft();
            while (current != null) {
                parent = current;
                current = current.getLeft();
            }
            return parent;
        }
    }
    // 找到二叉排序树的最大值,也就是最右边的孩子
    public Node findMaxNode() {
        Node current;
        Node parent;
        //
        if (root == null) {
            return null;
        } else {
            parent = root;
            current = parent.getRight();
            while (current != null) {
                parent = current;
                current = current.getRight();
            }
            return parent;
        }
    }
    // 先要找到节点,而后根据要删除节点的位置进行删除
    // 删除的节点有三种,叶子节点,有一个节点的节点,有两个节点的节点
    public boolean delete(int key) {
        Node current = root;
        Node parent = root;
        // 这里主要是为了区分删除的是左孩子仍是右孩子
        boolean isLeftChild = false;
        // 显然,当current.iData == key 时,current就是须要删除的节点
        // 在循环中利用parent保存了父类节点
        while (current.getData() != key) {
            parent = current;
            if (key < current.getData()) {
                isLeftChild = true;
                current = current.getLeft();
            } else {
                isLeftChild = false;
                current = current.getRight();
            }
            if (current == null)// 找不到key时返回false
                return false;
        }
        // 当节点为叶子节点的时候
        if (current.getLeft() == null && current.getRight() == null) {
            if (current == root)
                root = null;
            else if (isLeftChild)
                parent.setLeft(null);
            else
                parent.setRight(null);
        }
        // 当删除的节点为含有一个子节点的节点
        // 删除的节点只有一个左子节点时
        // 必需要考虑被删除的节点是左节点仍是右节点
        else if (current.getRight() == null) {
            if (current == root)// 要删除的节点为根节点
                root = current.getLeft();
            else if (isLeftChild)// 要删除的节点是一个左子节点
                parent.setLeft(current.getLeft());
            else
                parent.setRight(current.getLeft());// 要删除的节点是一个右子节点
        }
        // 当删除的节点为含有一个子节点的节点
        // 删除的节点只有一个右子节点时
        // 必需要考虑被删除的节点是左节点仍是右节点
        else if (current.getLeft() == null) {
            if (current == root)// 要删除的节点为根节点
                root = current.getRight();
            else if (isLeftChild)// 要删除的节点是一个左子节点
                parent.setLeft(current.getRight());
            else
                parent.setRight(current.getRight());// 要删除的节点是一个右子节点
        }
        // 当要删除的节点是含有两个节点的时候
        else
         {
            //首先要获取被删除节点的后继节点,current
             Node successor = getSuccessor(current);
             if(current == root)
                root = successor ;
             //这里已经屏蔽了后继节点是叶子和非叶子节点
             else if(isLeftChild)
                    parent.setLeft(successor);
             else
                    parent.setRight(successor);
             successor.setLeft(current.getLeft());
         }
        return true;
    }
    // 寻找后记节点,主要是当要删除的节点包含了两个子节点的时候
    // 返回后继节点,后继节点就是比要删除的节点的关键值要大的节点集合中的最小值。
    //后继节点要么是被删除节点的不包含左子节点的右节点,要么就是包含左子节点的右节点的子节点
    private Node getSuccessor(Node delNode)
    {
        // 后继节点的父节点
        Node successorParent = delNode;
        // 后继节点
        Node successor = delNode.getRight();
        //判断后继节点是否有左孩子
        Node current = successor.getLeft();
        while (current != null) {
            successorParent = successor;
            successor = current;
            current = current.getLeft();
        }
        //当该后继节点是属于包含左子节点的右节点的子节点
        if (successor != delNode.getRight())
        {
            successorParent.setLeft(successor.getRight());
            //链接被删除节点的右孩子
            successor.setRight(delNode.getRight());
        }
        return successor;
    }
    // 下面三种遍历树
    // 三种遍历均是采用递归实现的
    // 前序遍历
    public void preOrder(Node localRoot) {
        if (localRoot != null) {
            localRoot.displayNode();// 访问这个节点
            preOrder(localRoot.getLeft());// 调用自身来遍历左子树
            preOrder(localRoot.getRight());// 调用自身来遍历右子树
        }
    }
    // 中序遍历
    public void midOrder(Node localRoot) {
        if (localRoot != null) {
            preOrder(localRoot.getLeft());// 调用自身来遍历左子树
            localRoot.displayNode();// 访问这个节点
            preOrder(localRoot.getRight());// 调用自身来遍历右子树
        }
    }
    // 后续遍历
    public void lastOrder(Node localRoot) {
        if (localRoot != null) {
            preOrder(localRoot.getLeft());// 调用自身来遍历左子树
            preOrder(localRoot.getRight());// 调用自身来遍历右子树
            localRoot.displayNode();// 访问这个节点
        }
    }
}


二叉排序树的递归插入,递归遍历,递归查询app

package whut.tree;
//二叉树的存储,这里会创建一个二叉排序树,递归方式
public class NodeTree {
    public int value;
    public NodeTree left;
    public NodeTree right;
    //递归实现存储
    public void store(int value) {
        if (value < this.value) {
            if (left == null) {
                left = new NodeTree();
                left.value = value;
            } else {
                left.store(value);
            }
        } else if (value > this.value) {
            if (right == null)
            {
                right = new NodeTree();
                right.value = value;
            } else {
                right.store(value);
            }
        }
    }
    public boolean find(int value) {
        System.out.println("find happen " + this.value);
        if (value == this.value) {
            return true;
        } else if (value > this.value) {
            if (right == null)
                return false;
            return right.find(value);
        } else {
            if (left == null)
                return false;
            return left.find(value);
        }
    }
    //前序遍历
    public void preList() {
        System.out.print(this.value + ",");
        if (left != null)
            left.preList();
        if (right != null)
            right.preList();
    }
            
    //中序遍历
    public void middleList() {
        if (left != null)
            left.middleList();
        System.out.print(this.value + ",");
        if (right != null)
            right.middleList();
    }
     //后续遍历
    public void afterList() {
        if (left != null)
            left.afterList();
        if (right != null)
            right.afterList();
        System.out.print(this.value + ",");
    }
    public static void main(String[] args) {
        int[] data = new int[20];
        for (int i = 0; i < data.length; i++) {
            data[i] = (int) (Math.random() * 100) + 1;
            System.out.print(data[i] + ",");
        }
        System.out.println();
        NodeTree root = new NodeTree();
        root.value = data[0];
        for (int i = 1; i < data.length; i++) {
            root.store(data[i]);
        }
        //查询
        root.find(data[19]);
        //先序
        root.preList();
        System.out.println();
        //中序
        root.middleList();
        System.out.println();
        //后续
        root.afterList();
    }
}
相关文章
相关标签/搜索