题目链接:
按之字形顺序打印二叉树_牛客题霸_牛客网 (nowcoder.com)
题目简介:
描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
数据范围: 0≤n≤1500,树上每个节点的val满足 ∣val∣<=1500
要求:空间复杂度: O(n),时间复杂度:� O(n)例如:
给定的二叉树是{1,2,3,#,#,4,5}
该二叉树之字形层序遍历的结果是[
[1],
[3,2],
[4,5]
]
题目解法:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*BM27 按之字形顺序打印二叉树
*描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
数据范围: 0≤n≤1500,树上每个节点的val满足 ∣val∣<=1500
要求:空间复杂度:O(n) ,时间复杂度:O(n)
例如:
给定的二叉树是{1,2,3,#,#,4,5}
该二叉树之字形层序遍历的结果是
[
[1],
[3,2],
[4,5]
]
*/
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pRoot TreeNode类
* @return int整型二维数组
* @return int* returnSize 返回数组行数
* @return int** returnColumnSizes 返回数组列数
*/
//做这道题的时候,一直想着怎么按照是否反转来压栈,陷入了死胡同,看答案后,发现可以按照是否反转来弹栈,多思考不同的方法
int** Print(struct TreeNode* pRoot, int* returnSize, int** returnColumnSizes ) {
// write code hereI
if(!pRoot) return NULL;
*returnSize = -1;
*returnColumnSizes = (int*)malloc(sizeof(int)*1000);
int **res = (int**)malloc(sizeof(int*) * 1000);
struct TreeNode** st1 = (struct TreeNode**)malloc(sizeof(struct TreeNode*)*3000);
struct TreeNode** st2 = (struct TreeNode**)malloc(sizeof(struct TreeNode*)*3000);
// struct TreeNode *st1[6], *st2[6]; //调试代码
// int res[4][8] = {0}; //调试代码
int st1_i = -1, st2_i = -1;
int st2_i_Max; //用来装当前st2存储的元素最大数量
int LayerNodeCnt, tmpCnt;
int reverseFlag = 1;
struct TreeNode* node;
st1[++st1_i] = pRoot;
while(st1_i >= 0){
if(st1[st1_i] != NULL){
//先将st1的元素弹栈到st2
while(st1_i >= 0){
st2[++st2_i] = st1[st1_i--];
}
st2_i_Max = st2_i;
//根据reverseFlag来将st2的子节点压入st1
while(st2_i >= 0){
node = st2[st2_i];
if(node->left)st1[++st1_i] = node->left;
if(node->right)st1[++st1_i] = node->right;
st2_i--;
}
//将当前层节点加上标志压入st1
st2_i = st2_i_Max;
LayerNodeCnt = st2_i_Max+1;
while(st2_i >= 0){
st1[++st1_i] = st2[st2_i--];
st1[++st1_i] = NULL;
}
(*returnColumnSizes)[++(*returnSize)] = LayerNodeCnt;
res[(*returnSize)] = (int*)malloc(sizeof(int)*LayerNodeCnt);
st2_i_Max = 0, tmpCnt=0;
reverseFlag = !reverseFlag; //为下一次反转
}else{
st1_i--;
if(reverseFlag){ //根据是否反转来选择弹栈元素的存储位置(从前还是从后)
res[*returnSize][tmpCnt] = st1[st1_i--]->val;
}else{
res[*returnSize][LayerNodeCnt-tmpCnt-1] = st1[st1_i--]->val;
}
tmpCnt++;
}
}
(*returnSize)++;
return (int **)res;
}
/**************************end******************************************/
int main ()
{
int returnSize = 0;
int* returnColumnSizes;
// struct TreeNode n22 ={.val =5 , .left = NULL, .right = NULL};
// struct TreeNode n21 ={.val =4 , .left = NULL, .right = NULL};
// struct TreeNode n2 ={.val =3 , .left = &n21, .right = &n22};
// struct TreeNode n1 ={.val =2 , .left = NULL, .right = NULL};
// struct TreeNode root ={.val =1 , .left = &n1, .right = &n2};
struct TreeNode n222 ={.val =1 , .left = NULL, .right = NULL};
struct TreeNode n221 ={.val =3 , .left = NULL, .right = NULL};
struct TreeNode n212 ={.val =5 , .left = NULL, .right = NULL};
struct TreeNode n211 ={.val =7 , .left = NULL, .right = NULL};
struct TreeNode n22 ={.val =14 , .left = &n221, .right = &n222};
struct TreeNode n21 ={.val =10 , .left = &n211, .right = &n212};
struct TreeNode n2 ={.val =12 , .left = &n21, .right = &n22};
struct TreeNode n122 ={.val =9 , .left = NULL, .right = NULL};
struct TreeNode n121 ={.val =11 , .left = NULL, .right = NULL};
struct TreeNode n112 ={.val =13 , .left = NULL, .right = NULL};
struct TreeNode n111 ={.val =15 , .left = NULL, .right = NULL};
struct TreeNode n12 ={.val =6 , .left = &n121, .right = &n122};
struct TreeNode n11 ={.val =2 , .left = &n111, .right = &n112};
struct TreeNode n1 ={.val =4 , .left = &n11, .right = &n12};
struct TreeNode root ={.val =8 , .left = &n1, .right = &n2};
// struct TreeNode n1 ={.val =2 , .left = NULL, .right = NULL};
// struct TreeNode root ={.val =1 , .left = &n1, .right = NULL};
int** ret = Print(&root, &returnSize, &returnColumnSizes);
for(int i=0; i<returnSize; i++){
printf("\n");
for(int j=0; j<*(returnColumnSizes+i); j++)
printf("%d\t", ret[i][j]);
}
return 0;
}