Java实现二叉树基本操作

来源:互联网 发布:男士围巾织法 知乎 编辑:程序博客网 时间:2024/05/16 17:28

总结了下二叉树的基本操作。

创建二叉查找树
先序遍历二叉树(递归)
先序遍历二叉树(栈)
中序遍历二叉树(递归)
中序遍历二叉树(栈)
后序遍历二叉树(递归)
后序遍历二叉树(栈)
宽度优先遍历二叉树(队列)
利用二分法查找指定节点
获得二叉查找树的最小值
删除指定节点
源码如下:

package cn.com.cnn;import java.util.ArrayDeque;import java.util.Stack;public class MyTree {    public class Node {        int value;        Node leftChild;        Node rightChild;        public Node(int value) {            this.value = value;            leftChild = null;            rightChild = null;        }        public void display() {            System.out.print(value + " ");        }    }    public static void main(String[] args) {        int[] data = {2, 4, 1, 9, 70, 6, 10};        MyTree myTree = new MyTree();        Node root = null;        for(int i = 0; i < data.length; i++) {            root = myTree.insertNodeRec(root, data[i]);        }        System.out.print("中序遍历 ");        myTree.inOrderTranverse(root);        myTree.inOrderTranverseStack(root);        System.out.print("先序遍历 ");        myTree.preOrderTranverse(root);        myTree.preOrderTranverseStack(root);        System.out.print("后序遍历 ");        myTree.afterOrderTranverse(root);        myTree.afterOrderTranverseStack(root);        System.out.print("广度优先遍历 ");        myTree.widthTranverse(root);        Node findNode = myTree.findKey(root, 10);        System.out.println("查找到的值是" + findNode.value);        Boolean ifDelete = myTree.delete(root, 4);        System.out.println(ifDelete);    }    public Node createBinaryTree(int[] data) {        Node root = null;        if(data == null) {            return root;        }        MyTree myTree = new MyTree();        for(int i : data) {            root = myTree.insertNodeRec(root, i);        }        return root;    }    public void inOrderTranverse(Node root) {        if(root == null) {            return;        }        inOrderTranverse(root.leftChild);        root.display();        inOrderTranverse(root.rightChild);    }    public void inOrderTranverseStack(Node root) {        Stack<Node> nodes = new Stack<Node>();        Node current = root;        while(current != null || !nodes.isEmpty()) {            while(current != null) {                nodes.push(current);                current = current.leftChild;            }            if(!nodes.isEmpty()) {                current = nodes.pop();                current.display();                current = current.rightChild;            }        }    }    public void preOrderTranverse(Node root) {        if(root == null) {            return;        }        root.display();        preOrderTranverse(root.leftChild);        preOrderTranverse(root.rightChild);    }    public void preOrderTranverseStack(Node root) {        Stack<Node> nodes = new Stack<Node>();        Node current = root;        while(current != null || !nodes.isEmpty()) {            while(current != null) {                current.display();                nodes.push(current);                current = current.leftChild;            }            if(!nodes.isEmpty()) {                current= nodes.pop();                current = current.rightChild;            }        }    }    public void afterOrderTranverse(Node root) {        if(root == null) {            return;        }        afterOrderTranverse(root.leftChild);        afterOrderTranverse(root.rightChild);        root.display();    }    public void afterOrderTranverseStack(Node root) {        Stack<Node> nodes = new Stack<Node>();        Node current = root;        Node preNode = null;        while(current != null || !nodes.isEmpty()) {            while(current != null) {                nodes.push(current);                current = current.leftChild;            }            if(!nodes.isEmpty()) {                current = nodes.peek().rightChild;                if(current == null || current == preNode) {                    current = nodes.pop();                    current.display();                                      preNode =current;                    current = null;                }            }        }    }    //使用队列实现广度优先遍历    public void widthTranverse(Node root) {        ArrayDeque<Node> nodes = new ArrayDeque<Node>();        Node current = root;        nodes.add(current);        while(!nodes.isEmpty()) {            current =  nodes.remove();            current.display();            if(current.leftChild != null) {                nodes.add(current.leftChild);            }             if(current.rightChild != null) {                nodes.add(current.rightChild);            }        }    }    //二分查找    public Node findKey(Node root, int value) {        Node result = root;        while(true) {            if(result == null) {                return result;            }            if(result.value == value) {                return result;            } else if(result.value < value) {                result = result.rightChild;            } else {                result =  result.leftChild;            }        }    }    public Node insertNodeRec(Node root, int value) {        Node current =new Node(value);        if(root == null) {            root = current;            return root;         }        if(root.value < value) {            if(root.rightChild == null) {                root.rightChild = current;            } else {                root.rightChild = insertNodeRec(root.rightChild, value);                            }        } else {            if(root.leftChild == null) {                root.leftChild = current;            } else {                root.leftChild = insertNodeRec(root.leftChild, value);                          }        }        return root;    }    public Node insertNoRec(Node root, int value) {        Node current = new Node(value);        if(root == null) {            root = current;            return root;        }        Node tmp = root;        while(tmp != null) {            if(tmp.value < value) {                if(tmp.rightChild == null) {                    tmp.rightChild = current;                    break;                } else {                    tmp = tmp.rightChild;                    continue;                }            } else {                if(tmp.leftChild == null) {                    tmp.rightChild = current;                    break;                } else {                    tmp = tmp.rightChild;                    continue;                }            }        }        return root;    }    public int getMinValue(Node root) {        Node current = root;        while(current.leftChild != null) {            current = current.leftChild;        }        return current.value;    }    public boolean delete(Node root, int value) {        if(root == null) {            return false;        }        Node parent = null;        Node current = root;        Boolean isLeft =true;        while(current.value != value) {            parent = current;            if(current.value < value) {                current = current.rightChild;                isLeft = false;            } else {                current = current.leftChild;                isLeft = true;            }        }        //没找到该节点        if(current == null) {            return false;        }        if(current.leftChild == null && current.rightChild == null) {            if(current == root) {                root = null;            } else {                if(isLeft) {                    parent.leftChild = null;                } else {                    parent.rightChild = null;                }                           }        } else if(current.leftChild == null) {            if(current == root) {                root = current.rightChild;            } else if(isLeft) {                parent.leftChild = current.rightChild;            } else {                parent.rightChild = current.rightChild;            }        } else if(current.rightChild == null) {            if(current == root) {                root = current.leftChild;            } else if(isLeft) {                parent.leftChild = current.leftChild;            } else {                parent.rightChild = current.leftChild;            }        } else {            //左右子树都不为空,取右子树中值最小的和current值置换,再删除该最小节点。显然最小节点在右子树最左边。            int minNum = getMinValue(current.rightChild);            current.value = minNum;            //删除current的右子树的最左边点            Node deleteNodes = current.rightChild;            while(deleteNodes.leftChild != null) {                deleteNodes = deleteNodes.leftChild;            }            deleteNodes.leftChild = null;        }        //afterOrderTranverse(root);        return true;    }}