2018-03-09  本文已影响22人  官先生Y

二叉树的建立

public class TreeNode {

    public TreeNode left;
    public TreeNode right;
    public int value;
    public TreeNode next;
}
public class 二叉树的建立 {

    private static int counter = 0;//定义一个静态计数变量

    public static void main(String[] args) {
        int[] a = {1, 2, 3, 0, 0, 4, 0, 0, 5, 0, 0};
        createBiTree(a);
    }

    public static TreeNode createBiTree(int[] a) {
        TreeNode root = new TreeNode();
        createBiTree(root, a, counter);
        return root;
    }

    /**
     * 构造二叉树
     *
     * @param root 根节点
     * @param a    数据源
     * @param i    计数器
     * @return 根节点
     */
    private static TreeNode createBiTree(TreeNode root, int[] a, int i) {
        if (i < a.length) {
            if (a[i] == 0) {
                root = null;
            } else {
                TreeNode left = new TreeNode();
                TreeNode right = new TreeNode();
                root.left = createBiTree(left, a, ++counter);
                root.right = createBiTree(right, a, ++counter);
                root.value = a[i];
            }
        }
        return root;
    }
}

建立二叉树,利用了递归的原理,也就是在打印二叉树的前中后序遍历算法中打印结点的地方,改成了生成结点,给结点赋值的操作而已。

二叉树的遍历

二叉树前中后序遍历

public class 二叉树前中后遍历 {

    static void recursionPreoderTree(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.value + " ");
        recursionPreoderTree(root.left);
        recursionPreoderTree(root.right);
    }

    static void recursionInoderTree(TreeNode root) {
        if (root == null) {
            return;
        }
        recursionInoderTree(root.left);
        System.out.print(root.value + " ");
        recursionInoderTree(root.right);
    }

    static void recursionPostorderTree(TreeNode root) {
        if (root == null) {
            return;
        }
        recursionPostorderTree(root.left);
        recursionPostorderTree(root.right);
        System.out.print(root.value + " ");
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        recursionPreoderTree(root);
        System.out.println();
        recursionInoderTree(root);
        System.out.println();
        recursionPostorderTree(root);
    }
}

二叉树层序遍历(广度优先)

public class 二叉树层序遍历 {

    static void levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);

        while (!queue.isEmpty()) {
            TreeNode current = queue.poll();

            System.out.print(current.value + " ");
            if (current.left != null) {
                queue.add(current.left);
            }
            if (current.right != null) {
                queue.add(current.right);
            }
        }
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        levelOrder(root);
    }
}

用队列,每次遍历当前节点的时候,把该节点从队列拿出来,并且把它的子节点全部加入到队列中

题目

设置二叉树的next节点

public class 二叉树的next结点 {

    static void nextSiblings(TreeNode treeNode) {

        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(treeNode);

        //这个level没有实际用处,但是可以告诉大家怎么判断当前node是第几层。
        int level = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {

                TreeNode current = queue.poll();
                System.out.print(current.value + " ");

                if (current.left != null) {
                    queue.offer(current.left);
                }
                if (current.right != null) {
                    queue.offer(current.right);
                }

                if (i != size - 1) {
                    current.next = queue.peek();
                }
            }
            level++;
        }
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        nextSiblings(root);
    }
}

其实这个题目就是典型的层序遍历,使用队列就可以轻松解决,每次poll出来一个节点,判断是不是当前层的最后一个,如果不是,把其next设置成queue中的下一个节点就ok了。至于怎么判断当前节点是哪一层呢?使用当前queue的size做for循环。

翻转二叉树

public class 翻转二叉树 {

    static TreeNode reverseBinaryTree(TreeNode root) {
        if (root == null) {
            return null;
        } else {
            //左子树已翻转好
            TreeNode left = reverseBinaryTree(root.left);
            //右子树已翻转好
            TreeNode right = reverseBinaryTree(root.right);
            //交换左右子树
            root.right = left;
            root.left = right;
            return root;
        }
    }

}

分而治之 和 递归 的思想

铺平二叉树

public class 铺平二叉树_链表 {

    static TreeNode inflateBinaryTree(TreeNode root) {

        if (root == null) {
            return root;
        }

        //用递归的思想,把左右先铺平
        TreeNode left = inflateBinaryTree(root.left);
        TreeNode right = inflateBinaryTree(root.right);

        //把左指针和右指针先指向空。
        root.left = null;
        root.right = null;

        //假如左子树生成的链表为空,那么忽略它,把右子树生成的链表指向根节点的右指针
        if (left == null) {
            root.right = right;
            return root;
        }

        //如果左子树生成链表不为空,那么用while循环获取最后一个节点,并且它的右指针要指向右子树生成的链表的头节点
        root.right = left;
        TreeNode lastLeft = left;
        while (lastLeft.right != null) {
            lastLeft = lastLeft.right;
        }
        lastLeft.right = right;
        return root;
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        inflateBinaryTree(root);
    }

}

android的findViewById

View searchViewById(ViewGroup viewGroup, int id) {

        if (viewGroup == null) {
            return null;
        }

        int childCount = viewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = viewGroup.getChildAt(i);
            if (view.getId() == id) {
                return view;
            }

            if (view instanceof ViewGroup) {
                View temp = searchViewById((ViewGroup) view, id);
                if (temp != null) {
                    return temp;
                }
            }
        }
        return null;
    }

线索二叉树

中序线索化二叉树

public class 中序线索化二叉树 {

    private Node preNode;   //线索化时记录前一个节点

    //节点存储结构
    static class Node {
        String data;        //数据域
        Node left;          //左指针域
        Node right;         //右指针域
        boolean isLeftThread = false;   //左指针域类型  false:指向子节点、true:前驱或后继线索
        boolean isRightThread = false;  //右指针域类型  false:指向子节点、true:前驱或后继线索

        Node(String data) {
            this.data = data;
        }
    }

    /**
     * 通过数组构造一个二叉树(完全二叉树)
     *
     * @param array
     * @param index
     * @return
     */
    static Node createBinaryTree(String[] array, int index) {
        Node node = null;

        if (index < array.length) {
            node = new Node(array[index]);
            node.left = createBinaryTree(array, index * 2 + 1);
            node.right = createBinaryTree(array, index * 2 + 2);
        }

        return node;
    }

    public static void main(String[] args) {
        String[] array = {"A", "B", "C", "D", "E", "F", "G", "H"};
        Node root = createBinaryTree(array, 0);

        中序线索化二叉树 tree = new 中序线索化二叉树();
        tree.inThreadOrder(root);
    }

    private void inThreadOrder(Node root) {

        inThreadOrder(root.left);

        //左指针为空,将指针指向刚才访问过的结点
        //若preNode为null,则当前结点时第一个结点
        if (root.left == null) {
            root.isLeftThread = true;
            root.left = preNode;
        }

        // 前一个结点的后继结点指向当前结点
        // 当前结点的后继点只能由父节点指定
        if (preNode != null && preNode.right == null) {
            preNode.isRightThread = true;
            preNode.right = root;
        }

        preNode = root;

        inThreadOrder(root.right);

    }

}

和二叉树中序遍历的递归代码几乎完全一样。只不过将本是打印的结点的功能改成了线索化的功能。

上一篇 下一篇

猜你喜欢

热点阅读