请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
以题目中的二叉树为例,一步步分析。
当二叉树的根结点(结点1)打印之后,它的左子结点(结点2)和右子结点(结点3)先后保存到一个容器中。值得注意的是,在打印第二层的结点时,先打印结点3,后打印结点2。由此可见结点在这个容器中是后进先出的,因此该容器可以用栈来实现。 接着打印第二层的两个节点。根据题目定义,先打印结点3,再打印结点2,并把他们的子结点放入一个容器中。注意到,打印第三层时,先打印结点2的两个结点,后打印结点3的两个结点。这意味着,我们还可以用一个栈来保存结点2和结点3的子结点。 此外我们还注意到,第三层的结点是从左向右打印的。按照栈后进先出的特点,应该先保存7到栈中,再保存结点6,之后再分别保存结点5和结点4。也就是说,在打印第二层的时候,我们先保存右子结点到栈中,再保存左子结点到栈中。保存子结点的顺序和打印第一层时不一样。 接下来打印第三层。与之前一样,在打印第三层的同时,我们要把第四层的结点保存到一个栈中。由于第四层的打印顺序是从右到左,因此保存的顺序是从左到右。这和保存根结点的两个子结点的顺序是一样的。从上面的分析可以看出,按之字形顺序打印二叉树,需要两个栈。当我们在打印某一行的结点时,把下一层的结点保存到相应的栈中。如果当前打印的是奇数层,则先保存左子结点再保存右子结点到一个栈中;如果当前打印的是偶数层,则先保存右子结点再保存左子结点到另一个栈中。
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } }; */ class Solution { public: vector<vector<int> > Print(TreeNode* pRoot) { vector<vector<int>>res; if(pRoot==NULL) { return res; } stack<TreeNode*>s1; stack<TreeNode*>s2; s1.push(pRoot); TreeNode*temp; vector<int>tp; while(!s1.empty()||!s2.empty()) { if(!s1.empty()) { while(!s1.empty()) { temp=s1.top(); tp.push_back(temp->val); if(temp->left) s2.push(temp->left); if(temp->right) s2.push(temp->right); s1.pop(); } res.push_back(tp); tp.clear(); } else { while(!s2.empty()) { temp=s2.top(); tp.push_back(temp->val); if(temp->right) s1.push(temp->right); if(temp->left) s1.push(temp->left); s2.pop(); } res.push_back(tp); tp.clear(); } } return res; } };