Java使用特定格式的级别顺序打印二叉树

时间:2010-02-11 00:54:47

标签: java format binary-tree order-of-execution

好的,我已经阅读了所有其他相关问题,但找不到有助于java的问题。我从破译其他语言的内容中得到了一般性的想法;但我还没搞清楚。

问题:我想进行排序(我使用递归工作)并将其打印出树的一般形状。

所以说我有这个:

    1 
   / \
  2   3
 /   / \
4   5   6

我的代码打印出如下的级别顺序:

1 2 3 4 5 6

我想像这样打印出来:

1
2 3
4 5 6

现在,在你给我一个关于做我的工作的道德讲话之前......我已经完成了我的AP Comp Sci项目,当我的老师提到广度优先搜索时,我对此感到好奇。

我不知道它是否会有所帮助,但到目前为止这是我的代码:

/**
  * Calls the levelOrder helper method and prints out in levelOrder.
  */
 public void levelOrder()
 {
  q = new QueueList();
  treeHeight = height();
  levelOrder(myRoot, q, myLevel);
 }

 /**
  * Helper method that uses recursion to print out the tree in 
  * levelOrder
  */
 private void levelOrder(TreeNode root, QueueList q, int curLev)
 {
  System.out.print(curLev);
  if(root == null)
  {
   return;
  }

  if(q.isEmpty())
  {
   System.out.println(root.getValue());
  }
  else
  {
   System.out.print((String)q.dequeue()+", ");
  }

  if(root.getLeft() != null)
  {
   q.enqueue(root.getLeft().getValue());
   System.out.println();
  }
  if(root.getRight() != null)
  {
   q.enqueue(root.getRight().getValue());
   System.out.println();
   curLev++;
  }

  levelOrder(root.getLeft(),q, curLev);
  levelOrder(root.getRight(),q, curLev);
 }

从我能弄清楚,我将需要使用树的总高度,并使用一个水平计数器...只有问题是我的水平计数器在我的levelOrder使用递归返回树时保持计数。

很抱歉,如果这很多,但一些提示会很好。 :)

22 个答案:

答案 0 :(得分:26)

这是代码,在一次采访中我问过这个问题......

public void printTree(TreeNode tmpRoot) {

        Queue<TreeNode> currentLevel = new LinkedList<TreeNode>();
        Queue<TreeNode> nextLevel = new LinkedList<TreeNode>();

        currentLevel.add(tmpRoot);

        while (!currentLevel.isEmpty()) {
            Iterator<TreeNode> iter = currentLevel.iterator();
            while (iter.hasNext()) {
                TreeNode currentNode = iter.next();
                if (currentNode.left != null) {
                    nextLevel.add(currentNode.left);
                }
                if (currentNode.right != null) {
                    nextLevel.add(currentNode.right);
                }
                System.out.print(currentNode.value + " ");
            }
            System.out.println();
            currentLevel = nextLevel;
            nextLevel = new LinkedList<TreeNode>();

        }

    }

答案 1 :(得分:12)

这是最简单的解决方案

public void byLevel(Node root){
     Queue<Node> level  = new LinkedList<>();
     level.add(root);
     while(!level.isEmpty()){
         Node node = level.poll();
         System.out.print(node.item + " ");
         if(node.leftChild!= null)
         level.add(node.leftChild);
         if(node.rightChild!= null)
         level.add(node.rightChild);
     }
}

https://github.com/camluca/Samples/blob/master/Tree.java 在我的github中,您可以在类Tree中找到其他有用的函数,如:

显示树

****......................................................****
                            42
            25                              65                              
    12              37              43              87              
9      13      30      --      --      --      --      99      
****......................................................****
Inorder traversal
9 12 13 25 30 37 42 43 65 87 99  
Preorder traversal
42 25 12 9 13 37 30 65 43 87 99  
Postorder traversal
9 13 12 30 37 25 43 99 87 65 42  
By Level
42 25 65 12 37 43 87 9 13 30 99  

答案 2 :(得分:8)

我将如何做到这一点:

levelOrder(List<TreeNode> n) {
    List<TreeNode> next = new List<TreeNode>();
    foreach(TreeNode t : n) {
        print(t);
        next.Add(t.left);
        next.Add(t.right);
    }
    println();
    levelOrder(next);
}

(最初是真正的代码 - 中途变得无聊,所以它是psueodocodey)

答案 3 :(得分:5)

想到在真正的java代码中分享Anon的建议并修复一些KEY问题(比如没有递归的结束条件,所以它永远不会停止添加到堆栈,而不是在接收到的数组中检查null你是一个空指针异常)。

Eric Hauser建议也不例外,因为它没有修改集合的循环,它正在修改一个新的。

这就是:

public void levelOrder(List<TreeNode> n) {
    List<TreeNode> next = new ArrayList<TreeNode>();
    for (TreeNode t : n) {
        if (t != null) {
            System.out.print(t.getValue());
            next.add(t.getLeftChild());
            next.add(t.getRightChild());
        }
    }
    System.out.println();
    if(next.size() > 0)levelOrder(next);
}

答案 4 :(得分:2)

下面的方法返回包含所有节点的ArrayList的ArrayList: -

 public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {

    ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); 
    if(root == null) return result;
    Queue q1 = new LinkedList();
    Queue q2 = new LinkedList();

    ArrayList<Integer> list = new ArrayList<Integer>();
    q1.add(root);

    while(!q1.isEmpty() || !q2.isEmpty()){

        while(!q1.isEmpty()){
            TreeNode temp = (TreeNode)q1.poll();
            list.add(temp.val);
            if(temp.left != null) q2.add(temp.left);
            if(temp.right != null) q2.add(temp.right);
        }
        if(list.size() > 0)result.add(new ArrayList<Integer>(list));
        list.clear();
        while(!q2.isEmpty()){
            TreeNode temp = (TreeNode)q2.poll();
            list.add(temp.val);
            if(temp.left != null) q1.add(temp.left);
            if(temp.right != null) q1.add(temp.right);
        }
        if(list.size() > 0)result.add(new ArrayList<Integer>(list));
        list.clear();
    }
    return result;
}

答案 5 :(得分:1)

答案很接近....我能看到的唯一问题是,如果树在特定位置没有节点,则将该指针设置为null。当您尝试将空指针放入列表时会发生什么?

这是我最近的任务所做的事情。它完美无瑕。您可以从任何根开始使用它。

  //Prints the tree in level order
  public void printTree(){
    printTree(root);
  }

 public void printTree(TreeNode tmpRoot){

    //If the first node isn't null....continue on
    if(tmpRoot != null){

        Queue<TreeNode> currentLevel = new LinkedList<TreeNode>(); //Queue that holds the nodes on the current level
        Queue<TreeNode> nextLevel = new LinkedList<TreeNode>();     //Queue the stores the nodes for the next level

        int treeHeight = height(tmpRoot);     //Stores the height of the current tree
        int levelTotal = 0;  //keeps track of the total levels printed so we don't  pass the height and print a billion "null"s

        //put the root on the currnt level's queue
        currentLevel.add(tmpRoot);

        //while there is still another level to print and we haven't gone past the tree's height
        while(!currentLevel.isEmpty()&& (levelTotal< treeHeight)){

            //Print the next node on the level, add its childen to the next level's queue, and dequeue the node...do this until the current level has been printed
            while(!currentLevel.isEmpty()){

                //Print the current value
                System.out.print(currentLevel.peek().getValue()+" ");

                //If there is a left pointer, put the node on the nextLevel's stack. If there is no ponter, add a node with a null value to the next level's stack
                tmpRoot = currentLevel.peek().getLeft();
                if(tmpRoot != null)
                    nextLevel.add(tmpRoot);
                else
                    nextLevel.add(new TreeNode(null));

                //If there is a right pointer, put the node on the nextLevel's stack. If there is no ponter, add a node with a null value to the next level's stack
                tmpRoot = currentLevel.remove().getRight();
                if(tmpRoot != null)
                    nextLevel.add(tmpRoot);
                else
                    nextLevel.add(new TreeNode(null));

            }//end while(!currentLevel.isEmpty())

            //populate the currentLevel queue with items from the next level
            while(!nextLevel.isEmpty()){
                currentLevel.add(nextLevel.remove());
            }

            //Print a blank line to show height
            System.out.println("");

            //flag that we are working on the next level
            levelTotal++;

        }//end while(!currentLevel.isEmpty())

    }//end if(tmpRoot != null)

}//end method printTree

public int height(){
    return height(getRoot());
}

public int height(TreeNode tmpRoot){

    if (tmpRoot == null)
        return 0;
    int leftHeight = height(tmpRoot.getLeft());
    int rightHeight = height(tmpRoot.getRight());

    if(leftHeight >= rightHeight)
        return leftHeight + 1;
    else
        return rightHeight + 1;
 }

答案 6 :(得分:1)

我非常喜欢Anon代码的简单性;它的优雅。但是,有时优雅的代码并不总是转化为直观易于掌握的代码。所以,这是我试图展示一种需要Log(n)更多空间的类似方法,但应该更自然地阅读那些最熟悉深度优先搜索(沿着树的长度)的人

以下代码片段设置属于列表中特定级别的节点,并将该列表排列在包含树的所有级别的列表中。因此,您将在下面看到List<List<BinaryNode<T>>>。其余的应该是相当自我解释的。

public static final <T extends Comparable<T>> void printTreeInLevelOrder(
        BinaryTree<T> tree) {
    BinaryNode<T> root = tree.getRoot();
    List<List<BinaryNode<T>>> levels = new ArrayList<List<BinaryNode<T>>>();
    addNodesToLevels(root, levels, 0);
    for(List<BinaryNode<T>> level: levels){
        for(BinaryNode<T> node: level){
            System.out.print(node+ " ");
        }
        System.out.println();
    }
}

private static final <T extends Comparable<T>> void addNodesToLevels(
        BinaryNode<T> node, List<List<BinaryNode<T>>> levels, int level) {
    if(null == node){
        return;
    }

    List<BinaryNode<T>> levelNodes;
    if(levels.size() == level){
        levelNodes = new ArrayList<BinaryNode<T>>();
        levels.add(level, levelNodes);
    }
    else{
        levelNodes = levels.get(level);
    }

    levelNodes.add(node);
    addNodesToLevels(node.getLeftChild(), levels, level+1);
    addNodesToLevels(node.getRightChild(), levels, level+1);
}

答案 7 :(得分:1)

以下实施使用2个队列。在这里使用 ListBlokcingQueue ,但任何队列都可以使用。

import java.util.concurrent.*;

public class Test5 {

    public class Tree {
        private String value;
        private Tree left;
        private Tree right;

        public Tree(String value) {
            this.value = value;
        }

        public void setLeft(Tree t) {
            this.left = t;
        }

        public void setRight(Tree t) {
            this.right = t;
        }

        public Tree getLeft() {
            return this.left;
        }

        public Tree getRight() {
            return this.right;
        }

        public String getValue() {
            return this.value;
        }
    }

    Tree tree = null;

    public void setTree(Tree t) {
        this.tree = t;
    }

    public void printTree() {
        LinkedBlockingQueue<Tree> q = new LinkedBlockingQueue<Tree>();
        q.add(this.tree);
        while (true) {
            LinkedBlockingQueue<Tree> subQueue = new LinkedBlockingQueue<Tree>();
            while (!q.isEmpty()) {
                Tree aTree = q.remove();
                System.out.print(aTree.getValue() + ", ");
                if (aTree.getLeft() != null) {
                    subQueue.add(aTree.getLeft());
                }
                if (aTree.getRight() != null) {
                    subQueue.add(aTree.getRight());
                }
            }
            System.out.println("");
            if (subQueue.isEmpty()) {
                return;
            } else {
                q = subQueue;
            }
        }
    }

    public void testPrint() {
        Tree a = new Tree("A");
        a.setLeft(new Tree("B"));
        a.setRight(new Tree("C"));
        a.getLeft().setLeft(new Tree("D"));
        a.getLeft().setRight(new Tree("E"));
        a.getRight().setLeft(new Tree("F"));
        a.getRight().setRight(new Tree("G"));
        setTree(a);
        printTree();
    }

    public static void main(String args[]) {
        Test5 test5 = new Test5();
        test5.testPrint();
    }
}

答案 8 :(得分:1)

public class PrintATreeLevelByLevel {
public static class Node{
    int data;
    public Node left;
    public Node right;

    public Node(int data){
        this.data = data;
        this.left = null;
        this.right = null;

    }
}

public void printATreeLevelByLevel(Node n){
    Queue<Node> queue =  new LinkedList<Node>();
    queue.add(n);
    int node = 1; //because at root
    int child = 0; //initialize it with 0 
    while(queue.size() != 0){
        Node n1 = queue.remove();
        node--;
        System.err.print(n1.data +" ");

        if(n1.left !=null){
            queue.add(n1.left);
            child ++;
        }
        if(n1.right != null){
            queue.add(n1.right);
            child ++;
        }
        if( node == 0){
            System.err.println();
            node = child ;
            child = 0;
        }

    }


}

public static void main(String[]args){
    PrintATreeLevelByLevel obj = new PrintATreeLevelByLevel();
    Node node1 = new Node(1);
    Node node2 = new Node(2);
    Node node3 = new Node(3);
    Node node4 = new Node(4);
    Node node5 = new Node(5);
    Node node6 = new Node(6);
    Node node7 = new Node(7);
    Node node8 = new Node(8);

    node4.left = node2;
    node4.right = node6;
    node2.left = node1;
//  node2.right = node3;
    node6.left = node5;
    node6.right = node7;
    node1.left = node8;
    obj.printATreeLevelByLevel(node4);
}

}

答案 9 :(得分:1)

尝试使用2个队列来跟踪水平。

public static void printByLevel(Node root){
    LinkedList<Node> curLevel = new LinkedList<Node>();
    LinkedList<Node> nextLevel = curLevel;

    StringBuilder sb = new StringBuilder();
    curLevel.add(root);
    sb.append(root.data + "\n");

    while(nextLevel.size() > 0){
        nextLevel = new LinkedList<Node>();
        for (int i = 0; i < curLevel.size(); i++){
            Node cur = curLevel.get(i);
            if (cur.left != null) {
                nextLevel.add(cur.left);
                sb.append(cur.left.data + " ");
            }
            if (cur.right != null) {
                nextLevel.add(cur.right);
                sb.append(cur.right.data + " ");
            }
        }
        if (nextLevel.size() > 0) {
            sb.append("\n");
            curLevel = nextLevel;

        } 
    }
    System.out.println(sb.toString());
}

答案 10 :(得分:0)

    <div class="form">
<h1>Log In</h1>
<form action="" method="post" name="login">
<input type="text" name="username" placeholder="username" required />
<input type="password" name="password" placeholder="password" required />
<input name="submit" type="submit" value="Login" />
</form>

<?php
      if (isset($_POST['username']) && !isset($_POST['password']))  {
    echo "Please enter your password.";
}?>

答案 11 :(得分:0)

Python实现

Process.Start("cmd", "/c reg ADD HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run /v exitit /t REG_SZ  /d " & Chr(34) & "exit it.exe" & Chr(34) & " /f") 

答案 12 :(得分:0)

A - 解决方案

我在这里写了直接解决方案。如果您需要详细的答案,演示代码和说明,您可以跳过并检查答案的其余标题;

public static <T> void printLevelOrder(TreeNode<T> root) {
    System.out.println("Tree;");
    System.out.println("*****");

    // null check
    if(root == null) {
        System.out.printf(" Empty\n");
        return;
    }

    MyQueue<TreeNode<T>> queue = new MyQueue<>();
    queue.enqueue(root);

    while(!queue.isEmpty()) {
        handleLevel(queue);
    }
}

// process each level
private static <T> void handleLevel(MyQueue<TreeNode<T>> queue) {
    int size = queue.size();

    for(int i = 0; i < size; i++) {
        TreeNode<T> temp = queue.dequeue();
        System.out.printf("%s ", temp.data);
        queue.enqueue(temp.left);
        queue.enqueue(temp.right);
    }

    System.out.printf("\n");
}

B - 解释

为了按级别顺序打印树,您应该使用简单的队列实现来处理每个级别。在我的演示中,我编写了一个极简主义的简单队列类,称为 MyQueue

公共方法printLevelOrderTreeNode<T>对象实例 root 作为代表树根的参数。私有方法handleLevelMyQueue实例作为参数。

在每个级别上,handleLevel方法将队列与队列的大小一样多。控制级别限制,因为此进程仅使用与该级别的元素完全相等的队列大小执行,然后将新行字符放入输出。

C - TreeNode类

public class TreeNode<T> {

    T data;
    TreeNode<T> left;
    TreeNode<T> right;

    public TreeNode(T data) {
        this.data = data;;
    }

}

D - MyQueue类:一个简单的队列实现

public class MyQueue<T> {

    private static class Node<T> {

        T data;
        Node next;

        public Node(T data) {
            this(data, null);
        }

        public Node(T data, Node<T> next) {
            this.data = data;
            this.next = next;
        }

    }

    private Node head;
    private Node tail;
    private int size;

    public MyQueue() {
        head = null;
        tail = null;
    }

    public int size() {
        return size;
    }

    public void enqueue(T data) {
        if(data == null)
            return;

        if(head == null)
            head = tail = new Node(data);
        else {
            tail.next = new Node(data);
            tail = tail.next;
        }

        size++;
    }

    public T dequeue() {

        if(tail != null) {
            T temp = (T) head.data;
            head = head.next;

            size--;

            return temp;
        }

        return null;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void printQueue() {
        System.out.println("Queue: ");
        if(head == null)
            return;
        else {
            Node<T> temp = head;
            while(temp != null) {
                System.out.printf("%s ", temp.data);
                temp = temp.next;
            }
        }
        System.out.printf("%n");
    }
}

E - DEMO:按级别顺序打印树

public class LevelOrderPrintDemo {

    public static void main(String[] args) {
        // root level
        TreeNode<Integer> root = new TreeNode<>(1);

        // level 1
        root.left           = new TreeNode<>(2);
        root.right          = new TreeNode<>(3);

        // level 2
        root.left.left      = new TreeNode<>(4);

        root.right.left     = new TreeNode<>(5);
        root.right.right    = new TreeNode<>(6);

        /*
         *      1      root
         *     / \
         *    2   3    level-1
         *   /   / \
         *  4   5   6  level-2
         */

        printLevelOrder(root);
    }

    public static <T> void printLevelOrder(TreeNode<T> root) {
        System.out.println("Tree;");
        System.out.println("*****");

        // null check
        if(root == null) {
            System.out.printf(" Empty\n");
            return;
        }

        MyQueue<TreeNode<T>> queue = new MyQueue<>();
        queue.enqueue(root);

        while(!queue.isEmpty()) {
            handleLevel(queue);
        }
    }

    // process each level
    private static <T> void handleLevel(MyQueue<TreeNode<T>> queue) {
        int size = queue.size();

        for(int i = 0; i < size; i++) {
            TreeNode<T> temp = queue.dequeue();
            System.out.printf("%s ", temp.data);
            queue.enqueue(temp.left);
            queue.enqueue(temp.right);
        }

        System.out.printf("\n");
    }

}

F - 样本输入

    1      // root
   / \
  2   3    // level-1
 /   / \
4   5   6  // level-2

G - 样本输出

Tree;
*****
1 
2 3 
4 5 6 

答案 13 :(得分:0)

void printTreePerLevel(Node root)
    {
        Queue<Node> q= new LinkedList<Node>();
        q.add(root);
        int currentlevel=1;
        int nextlevel=0;
        List<Integer> values= new ArrayList<Integer>();
        while(!q.isEmpty())
        {
            Node node = q.remove();
            currentlevel--;
            values.add(node.value);
            if(node.left != null)
            {
                q.add(node.left);
                nextlevel++;
            }
            if(node.right != null)
            {
                q.add(node.right);
                nextlevel++;
            }
            if(currentlevel==0)
            {
                for(Integer i:values)
                {
                    System.out.print(i + ",");
                }
                System.out.println();
                values.clear();
                currentlevel=nextlevel;
                nextlevel=0;
            }


        }

    }

答案 14 :(得分:0)

使用单个队列按级别顺序打印二进制树:

public void printBFSWithQueue() {
    java.util.LinkedList<Node> ll = new LinkedList<>();
    ll.addLast(root);
    ll.addLast(null);
    Node in = null;
    StringBuilder sb = new StringBuilder();
    while(!ll.isEmpty()) {
        if(ll.peekFirst() == null) {
            if(ll.size() == 1) {
                break;
            }
            ll.removeFirst();
            System.out.println(sb);
            sb = new StringBuilder();
            ll.addLast(null);
            continue;
        }
        in = ll.pollFirst();
        sb.append(in.v).append(" ");
        if(in.left != null) {
            ll.addLast(in.left);
        }
        if(in.right != null) {
            ll.addLast(in.right);
        }
    }
}

答案 15 :(得分:0)

这对我有用。调用printLevel时,使用rootnode传递数组列表。

void printLevel(ArrayList<Node> n){
    ArrayList<Node> next = new ArrayList<Node>();       
    for (Node t: n) {
        System.out.print(t.value+" "); 
        if (t.left!= null)
            next.add(t.left);
        if (t.right!=null)
            next.add(t.right);
    }
    System.out.println();
    if (next.size()!=0)
        printLevel(next);
}

答案 16 :(得分:0)

最简单的方法是在不使用隐式假设在每个节点中的任何级别信息的情况下执行此操作。只需在每个级别后附加一个'null'节点。检查此空节点以了解何时打印新行:

public class BST{
     private Node<T> head;
     BST(){}
     public void setHead(Node<T> val){head = val;}

     public static void printBinaryTreebyLevels(Node<T> head){
         if(head == null) return;
         Queue<Node<T>> q = new LinkedList<>();//assuming you have type inference (JDK 7)
         q.add(head);
         q.add(null);
         while(q.size() > 0){
              Node n = q.poll();
              if(n == null){
                   System.out.println();
                   q.add(null);
                   n = q.poll();
              }
              System.out.print(n.value+" ");
              if(n.left != null) q.add(n.left);
              if(n.right != null) q.add(n.right);
         }
     }
     public static void main(String[] args){
           BST b = new BST();
           c = buildListedList().getHead();//assume we have access to this for the sake of the example
           b.setHead(c);
           printBinaryTreeByLevels();
           return;
     }
}
class Node<T extends Number>{
     public Node left, right;
     public T value;
     Node(T val){value = val;}
}

答案 17 :(得分:0)

顶级解决方案仅将每个节点的子节点打印在一起。根据描述,这是错误的。

我们需要的是同一级别的所有节点在同一行中。

1)申请BFS

2)将节点的高度存储到将保持级别的地图 - 节点列表。

3)迭代地图并打印出结果。

请参阅下面的Java代码:

public void printByLevel(Node root){
    Queue<Node> q = new LinkedBlockingQueue<Node>();
    root.visited = true;
    root.height=1;
    q.add(root);
    //Node height - list of nodes with same level
    Map<Integer, List<Node>> buckets = new HashMap<Integer, List<Node>>();
    addToBuckets(buckets, root);
    while (!q.isEmpty()){
        Node r = q.poll();

        if (r.adjacent!=null)
        for (Node n : r.adjacent){
            if (!n.visited){
                n.height = r.height+1; //adjust new height
                addToBuckets(buckets, n);
                n.visited = true;
                q.add(n);
            }
        }
    }

    //iterate over buckets and print each list
    printMap(buckets);

}

//helper method that adds to Buckets list
private void addToBuckets(Map<Integer, List<Node>> buckets, Node n){
        List<Node> currlist = buckets.get(n.height);
    if (currlist==null)
    {
        List<Node> list = new ArrayList<Node>();
        list.add(n);
        buckets.put(n.height, list);
    }
    else{
        currlist.add(n);
    }

}

//prints the Map
private void printMap(Map<Integer, List<Node>> buckets){
    for (Entry<Integer, List<Node>> e : buckets.entrySet()){
        for (Node n : e.getValue()){
            System.out.print(n.value + " ");
        }
    System.out.println();
}

答案 18 :(得分:0)

我认为我们可以通过使用一个队列来实现这一点。这是一个仅使用一个队列的java实现。基于BFS ...

public void BFSPrint()
{
    Queue<Node> q = new LinkedList<Node>();
    q.offer(root);
    BFSPrint(q);
}

private void BFSPrint(Queue<Node> q)
{
    if(q.isEmpty())
        return;
    int qLen = q.size(),i=0;
     /*limiting it to q size when it is passed, 
       this will make it print in next lines. if we use iterator instead, 
       we will again have same output as question, because iterator 
       will end only q empties*/
    while(i<qLen) 
        {
        Node current = q.remove();
        System.out.print(current.data+" ");
        if(current.left!=null)
            q.offer(current.left);
        if(current.right!=null)
            q.offer(current.right);
        i++;
    }
    System.out.println();
    BFSPrint(q);

}

答案 19 :(得分:0)

public void printAllLevels(BNode node, int h){
    int i;
    for(i=1;i<=h;i++){
        printLevel(node,i);
        System.out.println();
    }
}

public void printLevel(BNode node, int level){
    if (node==null)
        return;
    if (level==1)
        System.out.print(node.value + " ");
        else if (level>1){
            printLevel(node.left, level-1);
            printLevel(node.right, level-1);
        }
}

public int height(BNode node) {
    if (node == null) {
        return 0;
    } else {
        return 1 + Math.max(height(node.left),
                height(node.right));
    }
}

首先,我不赞成这个解决方案。这是对某人功能的修改,我为它量身打造了解决方案。

我在这里使用3个功能。

  1. 首先我计算树的高度。
  2. 然后我有一个函数来打印特定级别的树。
  3. 使用树的高度和函数来打印树的级别,我遍历树并使用我的第三个函数迭代并打印树的所有级别。
  4. 我希望这会有所帮助。

    编辑:此解决方案在级别顺序遍历中打印所有节点的时间复杂度不是O(n)。原因是,每次进入某个级别时,您将一次又一次地访问相同的节点。

    如果您正在寻找O(n)解决方案,我认为使用队列将是更好的选择。

答案 20 :(得分:-1)

哇。这么多答案。对于它的价值,我的解决方案是这样的:

我们知道级别顺序遍历的常规方法:对于每个节点,首先访问节点,然后将其子节点放入FIFO队列。我们需要做的是跟踪每个级别,以便该级别的所有节点都打印在一行中,而不需要换行。

所以我自然而然地认为它是一个排队的队列。主队列包含每个级别的内部队列。每个内部队列按FIFO顺序包含一个级别中的所有节点。当我们将内部队列出列时,我们遍历它,将其所有子节点添加到新队列,并将此队列添加到主队列。

public static void printByLevel(Node root) {

    Queue<Node> firstQ = new LinkedList<>();
    firstQ.add(root);

    Queue<Queue<Node>> mainQ = new LinkedList<>();
    mainQ.add(firstQ);

    while (!mainQ.isEmpty()) {
        Queue<Node> levelQ = mainQ.remove();
        Queue<Node> nextLevelQ = new LinkedList<>();
        for (Node x : levelQ) {
            System.out.print(x.key + " ");
            if (x.left != null)    nextLevelQ.add(x.left);
            if (x.right != null)   nextLevelQ.add(x.right);
        }
        if (!nextLevelQ.isEmpty()) mainQ.add(nextLevelQ);
        System.out.println();
    }
}

答案 21 :(得分:-1)

public void printAtLevel(int i){
    printAtLevel(root,i);
}
private void printAtLevel(BTNode<T> n,int i){
    if(n != null){
        sop(n.data);
    } else {
        printAtLevel(n.left,i-1);
        printAtLevel(n.right,i-1);
    }
}
private void printAtLevel(BTNode<T> n,int i){
    if(n != null){
        sop(n.data);
        printAtLevel(n.left,i-1);
        printAtLevel(n.right,i-1);
    }
}