数据结构算法(八) 之 树的 2 道面试题 60 & 61

  • 剑指 Offer 面试题 60(Java 版):把二叉树打印成多行

题目:从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印一行。

思路:用一个队列来保存将要打印的结点。为了把二叉树的每一行单独打印到一行里,我们需要两个变量:一个变量表示在当前的层中还没有打印的结点数,另一个变量表示下一次结点的数目。

show my code

/**
 * 按行打印二叉树
 * @author innovator
 *
 */
public class PrintTree {

    /**
     * 按照层来打印二叉树
     * @param root
     */
    public static void printTreeByLine(BinaryTreeNode root){
        
        if(root == null){
            return;
        }
        
        //用队列来装遍历到的节点
        Queue queue = new LinkedList<>();
        
        queue.add(root);
        //下一层节点数目
        int nextLevel = 0;
        //当前层中未被打印的节点数
        int toBePrinted = 1;
        
        while(!queue.isEmpty()){
            
            BinaryTreeNode current = queue.peek();
            //打印当前节点
            System.out.printf(" %d",current.value);
            
            //层序遍历
            if(current.leftNode != null){
                queue.add(current.leftNode);
                nextLevel ++;
            }
            
            if(current.rightNode != null){
                queue.add(current.rightNode);
                nextLevel ++;
            }
            
            //弹出当前节点,出队
            queue.poll();
            toBePrinted --;
            
            //当前层已经打印完毕
            if(toBePrinted == 0){
                //输出换行
                System.out.printf("\n");
                //从下层开始打印
                toBePrinted = nextLevel;
                nextLevel = 0;
            }
        }
    }
    
    
//                     8
//           6                    10
//      5         7          9          11
    public static void main(String[] args){
        BinaryTreeNode root =  new BinaryTreeNode(8);
        BinaryTreeNode node1 = new BinaryTreeNode(6);
        BinaryTreeNode node2 = new BinaryTreeNode(10);
        BinaryTreeNode node3 = new BinaryTreeNode(5);
        BinaryTreeNode node4 = new BinaryTreeNode(7);
        BinaryTreeNode node5 = new BinaryTreeNode(9);
        BinaryTreeNode node6 = new BinaryTreeNode(11);
        
        root.leftNode = node1;
        root.rightNode = node2;
        node1.leftNode = node3;
        node1.rightNode = node4;
        node2.leftNode = node5;
        node2.rightNode = node6;
    
        printTreeByLine(root);
    }
}
结果
  • 剑指 Offer 面试题 61(Java 版):按之字形顺序打印二叉树

题目:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,即第一行按照从左到右的顺序打印,第二层按照从右到左顺序打印,第三行再按照从左到右的顺序打印,其他以此类推。

思路:按之字形顺序打印二叉树需要两个栈。我们在打印某一行结点时,把下一层的子结点保存到相应的栈里。如果当前打印的是奇数层,则先保存左子结点再保存右子结点到一个栈里;如果当前打印的是偶数层,则先保存右子结点再保存左子结点到第二个栈里。

show my code

/**
 * 按照之字顺序打印二叉树
 * @author innovator
 *
 */
public class PrintTreeByZHI {

    /**
     * 按照之字顺序打印二叉树
     * @param root
     */
    public static void printTree(BinaryTreeNode root){
        
        if(root == null){
            return;
        }
        
        //存放奇数层的结点
        Stack stack1 = new Stack<>();
        //存放偶数层的结点
        Stack stack2 = new Stack<>();
        
        //是否在打印奇数层
        int printFlag = 1;
        
        BinaryTreeNode current;
        
        stack1.push(root);
        //还有结点在栈中未打印
        while(!stack1.isEmpty() || !stack2.isEmpty()){
            
            if(printFlag == 1){
                current = stack1.pop();
            }else{
                current = stack2.pop();
            }
            
            System.out.printf(" "+ current.value);
            
            //将下一层的结点入栈
            if(printFlag == 1){
                //压入偶数栈
                //先左后右
                if(current.leftNode != null){
                    stack2.push(current.leftNode);
                }
                
                if(current.rightNode != null){
                    stack2.push(current.rightNode);
                }
            }else{
                //压入奇数栈
                //先右后左
                if(current.rightNode != null){
                    stack1.push(current.rightNode);
                }
                
                if(current.leftNode != null){
                    stack1.push(current.leftNode);
                }
                
            }
            
            
            //打印完了奇数层,轮到偶数层了
            //加了前面的判断是为了防止当下一行为空的时候,会跑进去打印换行,打印完了当前的栈才允许切换flag
            if(printFlag == 1 && stack1.isEmpty()){
                System.out.printf("\n");
                printFlag = 0;
            }
            
            //打印完了偶数层,轮到奇数层了
            if(printFlag == 0 && stack2.isEmpty()){
                System.out.printf("\n");
                printFlag = 1;
            }
        }
    }
    
//                  8
//          6                    10
//      5         7          9          11
    public static void main(String[] args){
        BinaryTreeNode root =  new BinaryTreeNode(8);
        BinaryTreeNode node1 = new BinaryTreeNode(6);
        BinaryTreeNode node2 = new BinaryTreeNode(10);
        BinaryTreeNode node3 = new BinaryTreeNode(5);
        BinaryTreeNode node4 = new BinaryTreeNode(7);
        BinaryTreeNode node5 = new BinaryTreeNode(9);
        BinaryTreeNode node6 = new BinaryTreeNode(11);
        
        root.leftNode = node1;
        root.rightNode = node2;
        node1.leftNode = node3;
        node1.rightNode = node4;
        node2.leftNode = node5;
        node2.rightNode = node6;
    
        printTree(root);
    }
}
结果

你可能感兴趣的:(数据结构算法(八) 之 树的 2 道面试题 60 & 61)