leetcode-初级-二叉树层次遍历

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

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

我根据这个人的改写的,他用的是顺序存储的队列+广度优先搜索BFS完成对树的遍历https://blog.csdn.net/vfi7018/article/details/80585028

int GetdepthofTree(struct TreeNode* root){
    if (!root) return 0;
    int left = GetdepthofTree(root->left);
    int right = GetdepthofTree(root->right);
    if (left > right)
        return left+1;
    else
        return right+1;
}
 
 
//int** levelOrderBottom(struct TreeNode* root, int** columnSizes, int* returnSize) 
int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize){
    if (!root){
        return NULL;
    }
    //获取二叉树的深度,最大层数或者说
    int depth = *returnSize = GetdepthofTree(root);
    
    //ret是一个指向一个二维数组的指针,这一块地址是我们自己开辟的,需要malloc
    int** ret = (int**)malloc(depth*sizeof(int*));
    
    //columnSizes是一个指向指针的指针,这个地址已经指定了,就是说这个地址了存放的下一个地址已经确定了,但是下一个地址里存放的还是地址,这个地址任然不确定,那么就需要malloc了
    //*columnSizes是一个指向一个一维数组的指针,数组的大小也是depth
    
    *columnSizes = (int*)malloc(depth*sizeof(int));
    int front = 0, back = 0;
    struct TreeNode* queue[10000];
    queue[back++] = root;
    int count=0;
    while (front < back){
        int start = front, end = back;
        (*columnSizes)[count] = end - start;
        front = end;
        //开始的时候我们只给了ret的地址,因为ret是一个二维数组的起始地址,但是这个二维数组里面的一维数组的地址并没有确定,就需要malloc来确定
        ret[count] = (int*)malloc((end - start)*sizeof(int));
        for (int i=start; i<end; i++){
            ret[count][i-start] = queue[i]->val;
            if (queue[i]->left) queue[back++] = queue[i]->left;
            if (queue[i]->right) queue[back++] = queue[i]->right;
        }
        count++;
    }
    return ret;
}

这个是答案里耗时最少的,但很长:

#define RECURSE 1  /*测试数据卡这种办法,有高度非常大的偏斜树和高度较大的完美二叉树*/
#define QUEUE   2

#define ALGO_SEL 2

#if ALGO_SEL == RECURSE
    void levelOrder_recurse(int** data, const struct TreeNode* root, int** columnSizes, int* max_depth, int depth){
        if(root == NULL)
            return ;
        //获取最大深度
        if(*max_depth < depth)
            *max_depth = depth;
        //赋值
        data[depth][(*columnSizes)[depth]] = root->val;
        (*columnSizes)[depth] += 1;
        //递归左、右子树
        levelOrder_recurse(data, root->left,  columnSizes, max_depth, depth+1);
        levelOrder_recurse(data, root->right, columnSizes, max_depth, depth+1);
    }


    /**
     * 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().
     */
    #define MAX_RES 1000
    int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) {
        if(root == NULL){
            *returnSize = 0;
            return NULL;
        }

        int** res = (int**)malloc(sizeof(int*)*MAX_RES);
        assert(res != NULL);

        *columnSizes = (int*)malloc(sizeof(int)*MAX_RES);
        assert(*columnSizes != NULL);
        for(int i=0; i<MAX_RES; i++){
            (*columnSizes)[i] = 0;
        }
        for(int i=0; i<MAX_RES; i++){
            res[i] = (int*)malloc(sizeof(int)*100);//(int)(pow(2, i))
            assert(res[i] != NULL);
        }

        int max_depth = 0;
        levelOrder_recurse(res, root, columnSizes, &max_depth, 0);
        //printf("%d\n", max_depth);
        *returnSize = max_depth + 1;
        return res;
    }
#elif ALGO_SEL == QUEUE

    #define MAX_RES 1000
    #include<assert.h>
    #include<stdio.h>
    #include<stdlib.h>
    /*
     * 这是一个带有链队信息结点的链队列文件
     */
    #define DATA_TYPE struct TreeNode* 
    #define MAX_DATA_LEN 1000
    typedef struct queue_node_tag* p_queue_node;
    /*
     * 链队列结构体
     */
    typedef struct queue_node_tag{
        DATA_TYPE data;
        p_queue_node next;
    }queue_node;
    /*
     * 链队列的信息指针
     * 链表的头、尾巴以及长度信息
     */
    typedef struct queue_tag* p_queue;
    typedef struct queue_tag{
        p_queue_node front;
        p_queue_node rear;
        int queue_num;
    }queue;
    /*
     * 链队列的初始化
     * 初始化失败停止程序,因为可能系统内存满了或者奔溃了
     */
    p_queue queue_init(void){
        p_queue head = (p_queue)malloc(sizeof(queue));
        assert(head != NULL);
        head->front = NULL;
        head->rear  = NULL;
        head->queue_num = 0;
        return head;
    }

    /*
     * 判断链队列是否为空
     */
    int queue_is_empty(const p_queue head){
        return (0 == head->queue_num);
    }

    /*
     * 往链队列插入一个数据
     * 插入成功,返回1
     * 数据内存申请失败,返回0
     * 队列满返回-1
     */
    int queue_push(p_queue head, const DATA_TYPE insert_data){

        if(queue_is_full(head)){
            printf("queue is full!\n");
            return -1;
        }
        p_queue_node p_node = (p_queue_node)malloc(sizeof(queue_node));
        if(NULL == p_node){
            printf("malloc data:%d memory error!\n", insert_data);
            return 0;
        }
        /*
         * 插入到链队列尾巴
         */
        p_node->data = insert_data;
        p_node->next = NULL;
        /*
         *不是第一次插入
         */
        if(head->rear != NULL){
            head->rear->next = p_node;
            head->rear = p_node;
        } 
        /*
         * 第一次插入
         * 修正front与rear指针一样
         */ 
        else{
            head->front = p_node;
            head->rear  = p_node;
        }
        head->queue_num += 1;
        return 1;
    }

    /*
     * 往链队列弹出一个数据
     * 即从头出去
     * 若链队列为空,则返回-1
     */
    DATA_TYPE queue_pop(p_queue head){
        if(queue_is_empty(head)){
            printf("list queue_node is empty!\n");
            return -1;
        }
        DATA_TYPE head_data = head->front->data;
        p_queue_node p_temp;
        p_temp = head->front;
        head->front = p_temp->next;
        /* 
         * 如果是最后一个数据从队列出去
         * 修正一下rear指针为NULL
         */
        if(head->front == NULL){
            head->rear = NULL;
        }
        free(p_temp);
        head->queue_num -= 1;
        return head_data;
    }

    /*
     * 返回链队列的头结点数据
     * 若链队列为空,则返回-1
     */
    DATA_TYPE queue_top_element(const p_queue head){
        if(queue_is_empty(head)){
            printf("list queue is empty!\n");
            return -1;
        }
        else
            return head->front->data;
    }

    /*
     * 判断链队列是否满
     */
    int queue_is_full(const p_queue head){
        return (head->queue_num > MAX_DATA_LEN);
    }

    /*
     * 利用队列与BFS实现二叉树的深度遍历
     */
    int levelOrder_queue_traverse(int** res, int** columnSizes, const p_queue head, const struct TreeNode* root){
        queue_push(head, root);
        int depth = 0;
        while(!queue_is_empty(head)){
            (*columnSizes)[depth] = head->queue_num;
            res[depth] = (int*)malloc(sizeof(int)*(head->queue_num));
            assert(res[depth] != NULL);
            for(int i=0; i<(*columnSizes)[depth]; i++){
                struct TreeNode* tmp = queue_pop(head);
                res[depth][i] = tmp->val;
                if(tmp->left)
                    queue_push(head, tmp->left);
                if(tmp->right)
                    queue_push(head, tmp->right);
            }
            depth++;//遍历下一层
        }
        return depth;
    }
        
    int** levelOrder(struct TreeNode* root, int** columnSizes, int* returnSize) {
        if(root == NULL){
            *returnSize = 0;
            return NULL;
        }
        
        int** res = (int**)malloc(sizeof(int*)*MAX_RES);
        assert(res != NULL);

        *columnSizes = (int*)malloc(sizeof(int)*MAX_RES);
        assert(*columnSizes != NULL);
        /*
         * 先建立链队列
         */
        p_queue head = queue_init();
        *returnSize = levelOrder_queue_traverse(res, columnSizes, head, root);
        return res;
    }

#endif

猜你喜欢

转载自blog.csdn.net/mouthful/article/details/81123887