牛客-C语言解法-按之字形顺序打印二叉树

题目链接:

按之字形顺序打印二叉树_牛客题霸_牛客网 (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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值