如何直观形象地树状打印一棵二叉树?

作者: SunshineBrother | 来源:发表于2019-05-16 15:41 被阅读1次

    网上绝大部分的二叉树打印效果都十分潦草,也不够直观形象,最近自己用JS写了个图形化小工具BinaryTreeGraph,也用Java写了个打印器BinaryTreePrinter,还有个Objective-C版本BinaryTreePrinterOC
    具体代码实现请看github

    1、BinaryTreeGraph(JS版)

    image.png image.png image.png image.png image.png

    2、BinaryTreePrinter(Java版)

    2.1、简介

    • 树状打印一棵二叉树

    • 比如输入一棵二叉搜索树

      • [381, 12, 410, 9, 40, 394, 540, 35, 190, 476, 760, 146, 445, 600, 800]
    • 就会输出

    image.png
    • 或者输出
    image.png

    2.2、核心API

    public final class BinaryTrees {
        // 打印一棵二叉树
        public static void print(BinaryTreeInfo tree);
        public static void print(BinaryTreeInfo tree, PrintStyle style);
     
        // 打印一棵二叉树(打印完自动换行)
        public static void println(BinaryTreeInfo tree);
        public static void println(BinaryTreeInfo tree, PrintStyle style);
     
        // 获得一棵二叉树的打印字符串
        public static String printString(BinaryTreeInfo tree);
        public static String printString(BinaryTreeInfo tree, PrintStyle style);
     
        // 可选的打印样式
        public enum PrintStyle {
            LEVEL_ORDER, 
            INORDER
        }
    }
    
    

    2.3、示例

    ** 2.3.1、实现BinaryTreeInfo**

    • 根节点是谁?
    • 如何查找左节点?
    • 如何查找右节点?
    • 如何打印单个节点?
    /**
    * BinarySearchTree是你自己编写的二叉树类
    */
    public class BinarySearchTree<E> implements BinaryTreeInfo {
        /**这里省略了大量代码,只贴出了脉络代码**/
        
        private Node<E> root;
        private static class Node<E> {
            E element;
            Node<E> left;
            Node<E> right;
        }
        
        /********** BinaryTreeInfo **********/
        @Override
        public Object root() {
            // 根节点是谁?
            return root;
        }
     
        @Override
        public Object left(Object node) {
            // 如何查找左节点?
            return ((Node<E>)node).left;
        }
     
        @Override
        public Object right(Object node) {
            // 如何查找右节点?
            return ((Node<E>)node).right;
        }
     
        @Override
        public Object string(Object node) {
            // 如何打印单个节点?
            return ((Node<E>)node).element;
        }
        /********** BinaryTreeInfo **********/
    }
    
    

    2.3.2、打印

    // 随机生成的一棵二叉搜索树(random generation)
    BinarySearchTree<Integer> bst = ...;
     
    // PrintStyle.LEVEL_ORDER(层序打印)
    BinaryTrees.println(bst); 
     
    // PrintStyle.INORDER(中序打印)
    BinaryTrees.println(bst, PrintStyle.INORDER);
    
    
    image.png image.png

    2.3.3、生成字符串写入文件

    Files.writeToFile("F:/test/bst.txt", BinaryTrees.printString(bst));
    

    2.3.4、不需要定义二叉树类

    BinaryTrees.println(new BinaryTreeInfo() {
        @Override
        public Object root() {
            return 8;
        }
     
        @Override
        public Object left(Object node) {
            if (node.equals(8)) return 3;
            if (node.equals(3)) return 1;
            if (node.equals(6)) return 4;
            if (node.equals(14)) return 13;
            return null;
        }
     
        @Override
        public Object right(Object node) {
            if (node.equals(8)) return 10;
            if (node.equals(10)) return 14;
            if (node.equals(3)) return 6;
            if (node.equals(6)) return 7;
            return null;
        }
        
        @Override
        public Object string(Object node) {
            return node;
        }
    });
     
    BinaryTrees.println(new BinaryTreeInfo() {
        @Override
        public Object root() {
            return "Life";
        }
        
        @Override
        public Object left(Object node) {
            if (node.equals("Life")) return "Animal";
            if (node.equals("Person")) return "Man";
            if (node.equals("Animal")) return "Cat";
            if (node.equals("Dog")) return "Teddy";
            return null;
        }
        
        @Override
        public Object right(Object node) {
            if (node.equals("Life")) return "Person";
            if (node.equals("Person")) return "Woman";
            if (node.equals("Animal")) return "Dog";
            if (node.equals("Dog")) return "SingleDog";
            return null;
        }
        
        @Override
        public Object string(Object node) {
            return node;
        }
    });
    
    
    image.png image.png

    2.3.5、二叉堆

    public class BinaryHeap<E> implements BinaryTreeInfo {
        private int size;
        private E[] elements;
     
        @Override
        public Object root() {
            return 0;
        }
     
        @Override
        public Object left(Object node) {
            int leftIndex = ((int)node << 1) + 1;
            if (leftIndex >= size) return null;
            return leftIndex;
        }
     
        @Override
        public Object right(Object node) {
            int rightIndex = ((int)node << 1) + 2;
            if (rightIndex >= size) return null;
            return rightIndex;
        }
     
        @Override
        public Object string(Object node) {
            return elements[(int) node];
        }
    }
     
    BinaryHeap<Integer> heap = new BinaryHeap<>();
    for (int i = 0; i < 10; i++) {
        heap.add((int)(Math.random() * 100));
    }
    BinaryTrees.println(heap);
    
    
    image.png

    3、BinaryTreePrinterOC

    实现MJBinaryTreeInfo协议

    @interface MJBSTNode : NSObject {
    @public
        id _element;
        MJBSTNode *_left;
        MJBSTNode *_right;
    }
    @end
     
    @interface MJBinarySearchTree : NSObject <MJBinaryTreeInfo>
    @end
     
    @interface MJBinarySearchTree() {
        MJBSTNode *_root;
    }
    @end
     
    @implementation MJBinarySearchTree
    #pragma mark - MJBinaryTreeInfo
    - (id)left:(MJBSTNode *)node {
        return node->_left;
    }
     
    - (id)right:(MJBSTNode *)node {
        return node->_right;
    }
     
    - (id)string:(MJBSTNode *)node {
        return node->_element;
    }
     
    - (id)root {
        return _root;
    }
    @end
    
    

    打印

    [MJBinaryTrees println:bst];
     
    [MJBinaryTrees println:bst style:MJPrintStyleLevelOrder];
     
    [MJBinaryTrees println:bst style:MJPrintStyleInorder];
     
    NSString *str = [MJBinaryTrees printString:bst];
    NSString *file = @"/Users/mj/Desktop/1.txt";
    [str writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:nil];
    
    

    文章转载自: 如何直观形象地树状打印一棵二叉树?

    相关文章

      网友评论

        本文标题:如何直观形象地树状打印一棵二叉树?

        本文链接:https://www.haomeiwen.com/subject/wtpiaqtx.html