控制台打印二叉树&数组生成二叉树

初学的水平, 欢迎批评指正

LeetCode上都有生成二叉树的题解,在此简单解释部分内容.

数组生成二叉树

层序遍历生成二叉树, 每层结点入栈出栈,size 是上层结点个数,控制出栈结点数量

public static TreeNode levelForm(Integer[] source) {
        if (source == null || source.length == 0)
            return null;
        Queue<TreeNode> Queue = new LinkedList<>();
        TreeNode root = new TreeNode(source[0]);
        Queue.add(root);
        int j = 1;
        Pos:
        while (!Queue.isEmpty()) {
            int size = Queue.size();
            for (int i = 0; i < size; i++) {
                if (j == source.length) {
                    break Pos;
                }
                TreeNode t = Queue.poll();
                if (source[j] != null) {
                    t.left = new TreeNode(source[j]);
                    Queue.add(t.left);
                }
                j++;
                if (j == source.length) {
                    break Pos;
                }
                if (source[j] != null) {
                    t.right = new TreeNode(source[j]);
                    Queue.add(t.right);
                }
                j++;
            }
        }
        return root;
    }

控制台打印二叉树

01234567
left3:rootright
/\
15
/\/\
0246
  1. 将树在完全二叉树中的结点坐标位置补齐.
  2. 结点数字有最大长度maxNumLen , 或者可以写死最大数字占位宽度, 占位字符串是placeholder
  3. 确定每个结点在完全二叉树中的编号, 最下面一层均匀分布.完全二叉树的性质, 左子编号是其双亲编号的二倍.
  4. null以空格占位, 左右相邻的结点至少间隔一个固定长度maxNumLen .
  5. 从下往上, 双亲结点位置坐标, 取左右子位置坐标的平均值.
  6. 左子头上 ‘/’, 右子头上’\’, 在数字末位对齐

打印结果

IdPos数组的索引既是结点的在完全二叉树中的编号, 取值是位置坐标

[8, 4, 1211, 211, -6, 1011, 1554, 11111, -311, 5, 7, 9111, 11, 13, 10005]
getIdPos:
[0, 7, 3, 11, 1, 5, 9, 13, 0, 2, 4, 6, 8, 10, 12, 14]
                                       8
                   /                                       \
                   4                                    1211
         /                   \                   /                   \
       211                  -6                1011                1554
    /         \         /         \         /         \         /         \
11111      -311         5         7      9111        11        13     10005

代码如下

import java.util.*;

public class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;

    public TreeNode() {
    }

    public TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }

    public static List<List<Integer>> levelOrder(TreeNode root) {
        if (root == null)
            return new ArrayList<>();
        Queue<TreeNode> Queue = new LinkedList<>();
        List<List<Integer>> list = new ArrayList<>();
        Queue.add(root);
        while (!Queue.isEmpty()) {
            int size = Queue.size();
            ArrayList<Integer> list1 = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode t = Queue.poll();
                list1.add(t.val);
                if (t.left != null) {
                    Queue.add(t.left);
                }
                if (t.right != null) {
                    Queue.add(t.right);
                }
            }
            if (list1.size() > 0) {
                list.add(list1);
            }
        }
        return list;
    }

    static int[] idPos;
    static int minVal = Integer.MAX_VALUE;
    static int maxVal = Integer.MIN_VALUE;
    static HashMap<Integer, Integer> nodeIds = new HashMap<>();

    public static int treeGraph(TreeNode root, int id) {
        if (root == null)
            return 0;
        nodeIds.put(id, root.val);
        if (root.val < minVal) {
            minVal = root.val;
        }
        if (root.val > maxVal) {
            maxVal = root.val;
        }
        int a = treeGraph(root.left, id << 1);
        int b = treeGraph(root.right, (id << 1) + 1);
        return a >= b ? a + 1 : b + 1;
    }

    static int treeSizeLimit = 0;
    static String placeHolder4Num = " ";
    //    static String placeHolder4Num = "  ";

    public static StringBuilder formGraph(TreeNode root) {
        int depth = treeGraph(root, 1);
        if (depth == 0) {
            return new StringBuilder();
        }
        int limit = 1 << depth;
        treeSizeLimit = limit >> 1;
        idPos = new int[limit];
        int deepestLen = limit - 1;
        int index = deepestLen - 1;
        //最下面一层均匀分布
        for (int i = limit - 1; i >= treeSizeLimit; i--) {
            idPos[i] = index;
            index -= 2;
        }
        treeGraphPos(1);
        int maxNumLen = Math.max(getLenOfNum(maxVal), getLenOfNum(minVal));
        //占位字符串是placeholder
        StringBuilder placeholder = new StringBuilder();
        for (int i = 0; i < maxNumLen; i++) {
            placeholder.append(placeHolder4Num);
        }
        StringBuilder[] numberBuilder = new StringBuilder[depth];
        StringBuilder[] branchBuilder = new StringBuilder[depth];
        for (int i = 0; i < depth; i++) {
            numberBuilder[i] = new StringBuilder();
            branchBuilder[i] = new StringBuilder();
        }
        for (int j = 1, level = 0; j <= treeSizeLimit; level++, j <<= 1) {
            int id = j;
            for (; id < j << 1 && nodeIds.get(id) == null; id++) ;
            Integer val;
            for (int i = 0; i < idPos[id]; i++) {
                numberBuilder[level].append(placeholder);
                branchBuilder[level].append(placeholder);
            }
            int lastPos = idPos[id];
            for (; id < j << 1; id++) {
                val = nodeIds.get(id);
                if (val == null) {
                    continue;
                }
                int pos = idPos[id];
                if (pos != lastPos) {
                    for (int i = lastPos + 1; i < pos; i++) {
                        numberBuilder[level].append(placeholder);
                        branchBuilder[level].append(placeholder);
                    }
                    lastPos = pos;
                }
                int len = getLenOfNum(val);
                for (int i = 0; i < maxNumLen - len; i++) {
                    numberBuilder[level].append(placeHolder4Num);
                }
                numberBuilder[level].append(val);
                for (int i = 1; i < maxNumLen; i++) {
                    branchBuilder[level].append(placeHolder4Num);
                }
                branchBuilder[level].append(id % 2 == 0 ? '/' : '\\');
            }
        }
        StringBuilder res = new StringBuilder(numberBuilder[0]);
        res.append('\n');
        for (int i = 1; i < depth; i++) {
            res.append(branchBuilder[i]);
            res.append('\n');
            res.append(numberBuilder[i]);
            res.append('\n');
        }
        return res;
    }

    public static void treeGraphPos(int id) {
        //递归的终止条件
        if (id >= treeSizeLimit) {
            return;
        }
        treeGraphPos(id << 1);
        treeGraphPos((id << 1) + 1);
        idPos[id] = (idPos[id << 1] + idPos[(id << 1) + 1]) >> 1;
    }

    public static int getLenOfNum(int n) {
        int count = 0;
        if (n < 0) {
            count++;
        } else {
            n = -n;
        }
        while (n <= -10) {
            count++;
            n /= 10;
        }
        count++;
        return count;
    }

    public static TreeNode levelForm(Integer[] source) {
        if (source == null || source.length == 0)
            return null;
        Queue<TreeNode> Queue = new LinkedList<>();
        TreeNode root = new TreeNode(source[0]);
        Queue.add(root);
        int j = 1;
        Pos:
        while (!Queue.isEmpty()) {
            int size = Queue.size();
            for (int i = 0; i < size; i++) {
                if (j == source.length) {
                    break Pos;
                }
                TreeNode t = Queue.poll();
                if (source[j] != null) {
                    t.left = new TreeNode(source[j]);
                    Queue.add(t.left);
                }
                j++;
                if (j == source.length) {
                    break Pos;
                }
                if (source[j] != null) {
                    t.right = new TreeNode(source[j]);
                    Queue.add(t.right);
                }
                j++;
            }
        }
        return root;
    }

    public static int[] getIdPos() {
        return idPos;
    }

    public static void main(String[] args) {
        List<Integer[]> list = Arrays.asList(
                new Integer[]{0, 2, 4, 1, null, 3, -1, 5, 1, null, 6, 12, 8},
                new Integer[]{8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15},
                new Integer[]{},
                new Integer[]{2, 3},
                new Integer[]{8, 4, 1211, 211, -6, 1011, 1554, 11111, -311, 5, 7, 9111, 11, 13, 10005}
        );
        for (Integer[] ints : list) {
            System.out.println(Arrays.toString(ints));
            TreeNode node = levelForm(ints);
            levelOrder(node);

            StringBuilder builder = formGraph(node);
            System.out.println("getIdPos:");
            System.out.println(Arrays.toString(TreeNode.getIdPos()));
            System.out.println(builder);
            System.out.println("------------ ");
        }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值