LeetCode数据结构_C语言题解系列-树

题目一.二叉树的前序遍历(中序、后序)

144. 二叉树的前序遍历icon-default.png?t=N3I4https://leetcode.cn/problems/binary-tree-preorder-traversal/

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

示例 :

 

输入:root = [1,null,2,3]
输出:[1,2,3]

1.思路分析

二叉树是递归定义的数据结构,天然适宜使用递归遍历方法。之所以要采用“栈”作为辅助数据结构,是因为二叉链表指针单向,无法回溯。使用栈数据结构进行回溯,一般有两类方法:

1.递归方法:编译器分配系统栈,递归思路简洁、代码简单,但是树越深占用空间越大;

2.非递归方法:手工编写栈数据结构

非递归方法在对称二叉树判断中使用,在此不再赘述。

中序和后序遍历的递归方法与前序遍历的代码不同之处仅仅在输出时机不同而已,不再赘述。

2.AC代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

void* preTranverse(struct TreeNode* root,int* res,int* returnSize){
if(root==NULL)  return ;
   res[(*returnSize)++]=root->val;
    preTranverse(root->left,res,returnSize);
    preTranverse(root->right,res,returnSize); 
}

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* res=(int*)malloc(100*sizeof(int));
    *returnSize=0;
preTranverse(root,res,returnSize);

return res;
}

中序与后序AC代码也一并给出:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 void inorderTranverse(struct TreeNode* root,int* res,int* returnSize){
if(root==NULL)  return ;
   
    inorderTranverse(root->left,res,returnSize);
    res[(*returnSize)++]=root->val;
    inorderTranverse(root->right,res,returnSize); 
}

int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int* res=(int*)malloc(100*sizeof(int));
    *returnSize=0;
inorderTranverse(root,res,returnSize);

return res;
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

void postTranverse(struct TreeNode* root,int* res,int* returnSize){
if(root==NULL)  return ;
   
    postTranverse(root->left,res,returnSize);
    postTranverse(root->right,res,returnSize); 
    res[(*returnSize)++]=root->val;
}

int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int* res=(int*)malloc(100*sizeof(int));
    *returnSize=0;
postTranverse(root,res,returnSize);

return res;
}

题目二.二叉树的层序遍历

102. 二叉树的层序遍历icon-default.png?t=N3I4https://leetcode.cn/problems/binary-tree-level-order-traversal/

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 :

 

输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]

1.思路分析

队列法是常用的BFS遍历思路,但是本题和一般的BFS还有所不同:要求输出的不是一个遍历序列,而是要求将结果保存在一个矩阵内:这就要求保存树的深度和宽度(每一层结点数目为宽度)

保存在数组(*returnColumnSizes)内。BFS遍历逻辑非常简单,首先将根结点入队,在队非空时循环:队头元素出队,如果其左右指针非空,将对应子结点入队。

在这个过程中,可以发现一个严重的问题:队内可能同时存在多层结点,为了得出二叉树层宽,且不增加循环数量,选择“递推法”:

设n-1层二叉树有i个结点,那么经过i次出队(并访问其左右子结点)后,队内剩余结点数量为第n层二叉树宽度,而第0层(若根结点非空)层宽必为1,同理可递推后续每一层的层宽。

而层宽数组长度即为深度。

2.AC代码

/**
 * 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 *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
struct Queue{
    struct TreeNode* seqqueue[200];
    int rear;
    int front;
    int lenth;
};
bool empty(struct Queue* queue){
if(queue->lenth==0) return true;
else return false;
}
void ENQueue(struct Queue* queue,struct TreeNode* node){
if(queue->lenth==0) {
    queue->seqqueue[0]=node;
    queue->rear=0;
    queue->front=0;
}
else {
queue->rear=(queue->rear+1)%200;
queue->seqqueue[queue->rear]=node;
}
queue->lenth++;
}
struct TreeNode* DEQueue(struct Queue* queue){
struct TreeNode* ret=queue->seqqueue[queue->front];
if(queue->lenth!=1) queue->front=(queue->front+1)%200;
queue->lenth--;
return ret;
}

int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
struct Queue* queue=(struct Queue*)malloc(sizeof(struct Queue));
queue->rear=-1;queue->front=-1;
queue->lenth=0;
int** row=(int**)malloc(800*sizeof(int*));
for(int i=0;i<800;i++) row[i]=(int *)malloc(200*sizeof(int));
*returnColumnSizes=(int*)malloc(800*sizeof(int));
int i=0;int k=0;int j=0;
if(root==NULL) {
    *returnSize=0;
    return NULL;
}
else {
    struct TreeNode* p;
ENQueue(queue,root);
(*returnColumnSizes)[0]=1;
while(!empty(queue)){
    p=DEQueue(queue);
        k++;
    row[i][j]=p->val;
    if(p->left!=NULL)  ENQueue(queue,p->left);
    if(p->right!=NULL) ENQueue(queue,p->right);

if(k==(*returnColumnSizes)[i]){
  (*returnColumnSizes)[i+1]=queue->lenth; 
  k=0;
} 
if(j<(*returnColumnSizes)[i]-1) j++;
else {j=0;
    i++;
    }

}
*returnSize=i;
return row;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物质波波波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值