一个程序理解java二叉树-创建、递归非递归便利、获取路径

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class TreeNodeExample {  

    private int[] array = { 1, 2, 3, 4, 5, 6};  
    private static List<Node> nodeList = null;  

    /** 
     * 内部类:节点 
     *  
     * @author ocaicai@yeah.net @date: 2011-5-17 
     *  
     */  
    private static class Node {  
        Node leftChild;  
        Node rightChild;  
        int data;  

        Node(int newData) {  
            leftChild = null;  
            rightChild = null;  
            data = newData;  
        }  
    }  

    public void createBinTree() {  
        nodeList = new LinkedList<Node>();  
        // 将一个数组的值依次转换为Node节点  
        for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) {  
            nodeList.add(new Node(array[nodeIndex]));  
        }  
        // 对前lastParentIndex-1个父节点按照父节点与孩子节点的数字关系建立二叉树  
        for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) {  
            // 左孩子  
            nodeList.get(parentIndex).leftChild = nodeList  
                    .get(parentIndex * 2 + 1);  
            // 右孩子  
            nodeList.get(parentIndex).rightChild = nodeList  
                    .get(parentIndex * 2 + 2);  
        }  
        // 最后一个父节点:因为最后一个父节点可能没有右孩子,所以单独拿出来处理  
        int lastParentIndex = array.length / 2 - 1;  
        // 左孩子  
        nodeList.get(lastParentIndex).leftChild = nodeList  
                .get(lastParentIndex * 2 + 1);  
        // 右孩子,如果数组的长度为奇数才建立右孩子  
        if (array.length % 2 == 1) {  
            nodeList.get(lastParentIndex).rightChild = nodeList  
                    .get(lastParentIndex * 2 + 2);  
        }  
    }  

    /** 
     * 先序遍历 
     *  
     * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 
     *  
     * @param node 
     *            遍历的节点 
     */  
    public static void preOrderTraverse(Node node) {  
        if (node == null)  
            return;  
        System.out.print(node.data + " ");  
        preOrderTraverse(node.leftChild);  
        preOrderTraverse(node.rightChild);  
    }  

    /** 
     * 中序遍历 
     *  
     * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 
     *  
     * @param node 
     *            遍历的节点 
     */  
    public static void inOrderTraverse(Node node) {  
        if (node == null)  
            return;  
        inOrderTraverse(node.leftChild);  
        System.out.print(node.data + " ");  
        inOrderTraverse(node.rightChild);  
    }  

    /** 
     * 后序遍历 
     *  
     * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 
     *  
     * @param node 
     *            遍历的节点 
     */  
    public static void postOrderTraverse(Node node) {  
        if (node == null)  
            return;  
        postOrderTraverse(node.leftChild);  
        postOrderTraverse(node.rightChild);  
        System.out.print(node.data + " ");  
    }  


    /** 非递归实现前序遍历 */  
    protected static void iterativePreorder(Node p) {  
        Stack<Node> stack = new Stack<Node>();  
        if (p != null) {  
            stack.push(p);  
            while (!stack.empty()) {  
                p = stack.pop();  
                visit(p);  
                if (p.rightChild != null)  
                    stack.push(p.rightChild);  
                if (p.leftChild != null)  
                    stack.push(p.leftChild);  
            }  
        }  
    }  

    /** 非递归实现后序遍历 */  
    protected static void iterativePostorder(Node p) {  
        Node q = p;  
        Stack<Node> stack = new Stack<Node>();  
        while (p != null) {  
            // 左子树入栈  
            for (; p.leftChild != null; p = p.leftChild)  
                stack.push(p);  
            // 当前节点无右子或右子已经输出  
            while (p != null && (p.rightChild == null || p.rightChild == q)) {  
                visit(p);  
                q = p;// 记录上一个已输出节点  
                if (stack.empty())  
                    return;  
                p = stack.pop();  
            }  
            // 处理右子  
            stack.push(p);  
            p = p.rightChild;  
        }  
    }  

    /** 非递归实现中序遍历 */  
    protected static void iterativeInorder(Node p) {  
        Stack<Node> stack = new Stack<Node>();  
        while (p != null) {  
            while (p != null) {  
                if (p.rightChild != null)  
                    stack.push(p.rightChild);// 当前节点右子入栈  
                stack.push(p);// 当前节点入栈  
                p = p.leftChild;  
            }  
            p = stack.pop();  
            while (!stack.empty() && p.rightChild == null) {//没有右子树,直接出栈  
                visit(p);  
                p = stack.pop();  
            }  
            visit(p);有右子树,循环  
            if (!stack.empty())  
                p = stack.pop();  
            else  
                p = null;  
        }  
    }   


    /** 访问节点 */  
    public static void visit(Node p) {  
        System.out.print(p.data + " ");  
    }  


    /************************************************************************/
    public static List<String> binaryTreePaths(Node root) {  
        List<String> answer = new ArrayList<String>();  
        if (root != null) searchBT(root, "", answer);  
        return answer;  
    }  

    private static void searchBT(Node root, String path, List<String> answer) {  
        if (root.leftChild == null && root.rightChild == null) answer.add(path + root.data);  
        if (root.leftChild != null)  searchBT(root.leftChild, path + root.data + "-", answer);  
        if (root.rightChild != null) searchBT(root.rightChild, path + root.data + "-", answer);  
    }
    /************************************************************************/

    public static void main(String[] args) {  
        TreeNodeExample binTree = new TreeNodeExample();  
        binTree.createBinTree();  
        // nodeList中第0个索引处的值即为根节点  
        Node root = nodeList.get(0);  

        System.out.println("先序遍历:");
        System.out.print("递归实现-->");
        preOrderTraverse(root); 
        System.out.println(); 
        System.out.print("非递归实现-->");
        iterativePreorder(root);
        System.out.println();  

        System.out.println("中序遍历:");
        System.out.print("递归实现-->"); 
        inOrderTraverse(root); 
        System.out.println(); 
        System.out.print("非递归实现-->");
        iterativeInorder(root);
        System.out.println();  

        System.out.println("后序遍历:");  
        System.out.print("递归实现-->");
        postOrderTraverse(root);  
        System.out.println();  
        System.out.print("非递归实现-->");
        iterativePostorder(root);
        System.out.println();  


        //获取二叉树上的所有路径
        List<String> result = binaryTreePaths(root);
        System.out.println("二叉树上的所有路径");
        for(String path: result){
            System.err.println(path);
        }
    }  

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

专注网赚的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值