#数据结构与算法学习笔记#剑指Offer57:按之字形顺序打印二叉树(Java、C/C++)

2019.2.26     《剑指Offer》从零单刷个人笔记整理(66题全)目录传送门​​​​​​​

之前做过层序遍历二叉树的题:#数据结构与算法学习笔记#剑指Offer21:从上往下打印二叉树/层次遍历二叉树(Java、C/C++)。这道题其实是层序遍历的升级版,但是思想是一样的:层序遍历利用栈,之字遍历利用双向链表Tree。

情况有点复杂,需要分奇数偶数行考虑,

当为奇数行时,Tree出栈后->前,压栈右->左

当为偶数行时,Tree出栈后->前,压栈左->右

过程中需要一个临时压栈序列Temp,防止在压栈出栈过程中产生冲突。

如果用下图这样一棵简单的树来模拟一下,过程大概是:

1.Tree先放入第0行【1】

2.第1行,Tree出栈顺序:【1】,Temp压栈顺序:【5】、【2】

3.第2行,Tree出栈顺序:【2】,【5】,Temp压栈顺序:【3】,【4】,【6】

压栈即打印。


题目描述

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


Java实现:

/**
 * 
 * @author ChopinXBP
 * 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
 *
 */

import java.util.ArrayList;
import java.util.LinkedList;

public class PrintZTree_58 {
	
	public static class TreeNode {
	    int val = 0;
	    TreeNode left = null;
	    TreeNode right = null;

	    public TreeNode(int val) {
	        this.val = val;
	    }
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TreeNode pHead = new TreeNode(0);
		TreeNode p1= new TreeNode(1);
		TreeNode p2= new TreeNode(2);
		TreeNode p3= new TreeNode(3);
		TreeNode p4= new TreeNode(4);
		TreeNode p5= new TreeNode(5);
		TreeNode p6= new TreeNode(6);
		pHead.left = p1;
		pHead.right = p2;
		p1.left = p3;
		p1.right = p4;
		p2.left = p5;
		p2.right = p6;
		
		ArrayList> result = Print(pHead);
		for(int i = 0; i < result.size(); i++) {
			for(int j = 0; j < result.get(i).size(); j++) {
				System.out.print(result.get(i).get(j) + " ");
			}
			System.out.println(" ");
		}
	}

    public static ArrayList> Print(TreeNode pRoot) {
    	ArrayList> result = new ArrayList<>();
    	if(pRoot == null)return result;
    	
    	
    	LinkedList tree = new LinkedList<>(); 
    	
    	//放入根节点
    	tree.add(pRoot);
    	ArrayList root = new ArrayList<>();
    	root.add(pRoot.val);
    	result.add(root);
    	
    	//设定打印标志
    	boolean printflag = true;
    	while(!tree.isEmpty()) {
    		//当printflag为真时从右向左打印,反之从左向右
    		TreeNode pNode;
    		ArrayList list = new ArrayList<>();
    		LinkedList temp = new LinkedList<>();	//临时存储压栈结点,防止删除冲突 
    		int num = tree.size();
    		//奇数行printflag=true,出栈后->前,压栈右->左
    		if(printflag) {    			
        		for(int i = 0; i < num; i++) {
        			pNode = tree.pollLast();
        			if(pNode.right != null) {
        				temp.add(pNode.right);
        				list.add(pNode.right.val);
        			}
        			if(pNode.left != null) {
        				temp.add(pNode.left);
        				list.add(pNode.left.val);
        			}      			
        		}
        		printflag = false;
    		}
    		//偶数行printflag=false,出栈后->前,压栈左->右
    		else {
    			for(int i = 0; i < num; i++) {
        			pNode = tree.pollLast();
        			if(pNode.left != null) {
        				temp.add(pNode.left);
        				list.add(pNode.left.val);
        			} 
        			if(pNode.right != null) {
        				temp.add(pNode.right);
        				list.add(pNode.right.val);
        			}
        		}  
        		printflag = true;
    		}
    		
    		if(!temp.isEmpty()) tree.addAll(temp);
    		if(!list.isEmpty()) result.add(list);
    	}
    	return result;
    }
}

C++实现示例:

class Solution {
public:
    vector > Print(TreeNode* pRoot) {
        vector> res;
        if(pRoot == NULL)
            return res;
        queue que;
        que.push(pRoot);
        bool even = false;
        while(!que.empty()){
            vector vec;
            const int size = que.size();
            for(int i=0; ival);
                if(tmp->left != NULL)
                    que.push(tmp->left);
                if(tmp->right != NULL)
                    que.push(tmp->right);
            }
            if(even)
                std::reverse(vec.begin(), vec.end());
            res.push_back(vec);
            even = !even;
        }
        return res;
    }
     
};

#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#

你可能感兴趣的:(C/C++,数据结构与算法,剑指Offer,JAVA,数据结构与算法,剑指Offer,二叉树,层序遍历,双向链表)