Zigzag level traversal of [leetcode] binary tree

Posted by bjdouros on Wed, 01 Jan 2020 16:15:23 +0100

Problem Description:

Given a binary tree, it returns the zigzag level traversal of its node values. (that is, first from left to right, then from right to left to traverse the next layer, and so on, alternating between layers).

For example:
Given a binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

Return the zigzag level traversal as follows:

[
  [3],
  [20,9],
  [15,7]
]

Solutions:

1. First, calculate the height of the tree, which can be solved recursively. The height is mainly used to declare the number of rows of the returned array, that is, the value of int* returnSize in the given function header;

2. Declare the returned array variable: int **result=(int **)malloc(sizeof(int *)*depth); / / store the number of each layer of nodes as required

3. Declare to temporarily store the array variables of each layer node of tree, because the stored pointer is to the node, declare as follows: struct treenode * * temp = (struct treenode * *) malloc (sizeof (struct treenode * *) * depth);

4. According to the requirements of the topic, start to traverse the nodes line by line. It can be seen that the odd rows are traversed from right to left, and the even rows are traversed from left to right (counting from 0).

The submission code is as follows:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *columnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int getDepth(struct TreeNode* root)
{
    if(root==NULL)
    {
        return 0;
    }
    int leftDepth=getDepth(root->left);
    int rightDepth=getDepth(root->right);
    int depth=leftDepth>rightDepth?leftDepth:rightDepth;
    return depth+1;
}

int** zigzagLevelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) {
    if(root==NULL)
    {
        return NULL;
    }
    int depth=getDepth(root);
    *returnSize=depth;//The height of the tree, that is, the number of rows returned to the array
    int **result=(int **)malloc(sizeof(int *)*depth);//Store the number of nodes in each layer as required
    *columnSizes=(int *)malloc(sizeof(int)*depth);//Number of nodes in each row of the tree
    result[0]=(int *)malloc(sizeof(int));
    result[0][0]=root->val;
    (*columnSizes)[0]=1;
    
    struct TreeNode*** temp=(struct TreeNode ***)malloc(sizeof(struct TreeNode**)*depth);
    temp[0]=(struct TreeNode**)malloc(sizeof(struct TreeNode*));
    temp[0][0]=root;
    
    int i=0;
    for(i=0;i<depth-1;i++)//i represents the layer number of the current tree, counting from 0. Note that i < depth-1, because there are no child nodes in the last row of nodes, no need to traverse. If i < depth, the following error will be reported: free(): invalid next size (fast): 0x0000000001d294d0 * * -- because the row tree declaring result or temp array has only depth, if i=depth-1 continues to execute, result or temp will continue to divide With one line, the number of declared lines is exceeded, so the pointer is polluted.
    {
        int tempLen=(*columnSizes)[i]*2;//Maximum number of nodes in row i+1
        temp[i+1]=(struct TreeNode **)malloc(sizeof(struct TreeNode*)*tempLen);//Array for temporary storage of nodes in row i+1
        (*columnSizes)[i+1]=0;
 
        result[i+1]=(int *)malloc(sizeof(int)*tempLen);//Store the value of node in line i+1

        int nodes=(*columnSizes)[i];
        int j=0;
        if(i%2==0)//If i is even, the next line should be traversed from right to left
        {            
            for(j=nodes-1;j>=0;j--)
            {
                if(temp[i][j]->right!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->right->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->right;
                }
                if(temp[i][j]->left!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->left->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->left;
                }                
            }
        }
        else//If i is an odd number, the next line should be traversed from left to right
        {
            for(j=nodes-1;j>=0;j--)
            {
                if(temp[i][j]->left!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->left->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->left;
                }                
                if(temp[i][j]->right!=NULL)
                {
                    result[i+1][(*columnSizes)[i+1]]=temp[i][j]->right->val;
                    temp[i+1][(*columnSizes)[i+1]++]=temp[i][j]->right;
                }
            }
        }
    }
    
    free(temp);
    
    printf("columnSize:");
    for(i=0;i<depth;i++)
    {
        printf("%d,",(*columnSizes)[i]);
    }
    printf("\n returnSize=%d\n",*returnSize);;
    
    return result;
}