LeetCode题解:从先序与中序遍历构建二叉树

需积分: 50 539 下载量 187 浏览量 更新于2024-08-09 收藏 1.03MB PDF 举报
"二叉树的构建方法-LeetCode题解-《scrum精髓:敏捷转型指南》读书笔记" 在二叉树的构建问题中,本节主要关注如何根据先序遍历(Preorder Traversal)和中序遍历(Inorder Traversal)序列来重建原始的二叉树。这个问题在数据结构和算法领域非常经典,特别是在面试和在线编程挑战如LeetCode中常见。这里,我们探讨的是LeetCode的一道题目,具体问题为:给定一棵二叉树的先序遍历和中序遍历序列,构造该二叉树。 **先序遍历**(Preorder Traversal)顺序是:**根节点 -> 左子树 -> 右子树**。 **中序遍历**(Inorder Traversal)顺序是:**左子树 -> 根节点 -> 右子树**。 **问题描述**: 给定一个二叉树的先序遍历和中序遍历序列,构建这棵树。假设树中没有重复的元素。 **解决方案**: 构建二叉树的关键在于利用两个遍历序列的特性。先序遍历的第一个元素是整棵树的根节点,而在中序遍历中,这个根节点将左右子树分开。因此,我们可以首先找到中序遍历中根节点的位置,然后分别对左右子树进行递归操作。 在提供的代码中,`Solution` 类有一个 `buildTree` 函数,它接受两个整数向量(先序和中序遍历的结果),并返回一个指向二叉树节点的指针。代码首先处理边界情况,即遍历序列为空的情况。接着,创建一个新的根节点,其值等于先序遍历的第一个元素,然后通过`find`函数定位到中序遍历序列中根节点的位置。计算左子树的大小(即从中序遍历的起始位置到根节点的位置之间的元素个数),并递归地构建左子树和右子树。 代码使用模板类`InputIterator`,使得函数可以接受各种类型的迭代器,增强了通用性。递归调用 `buildTree` 函数,每次处理一部分先序和中序遍历的序列,直至构建完整的二叉树。 **复杂度分析**: 时间复杂度是 **O(n)**,其中 n 是树中节点的数量。我们访问每个节点一次,因此时间复杂度是线性的。 空间复杂度是 **O(logn)**,这是由于递归调用的栈深度,最坏情况下达到二叉树的高度,即 logn 层。 此外,这个代码遵循了特定的编程风格,例如: - 使用C++11的特性,如`nullptr`、`auto`和`begin()`、`end()`函数。 - 尽量保持代码简洁,如优先使用递归而不是栈来解决问题。 - 不进行防御性编程,例如不检查动态内存分配失败或函数参数的有效性,这是基于在线编程环境的假设。 **适用场景**: 这个知识点对于理解和解决二叉树相关的编码问题至关重要,特别是涉及到二叉树序列化和反序列化的问题。在准备面试或者参加算法竞赛时,掌握这类问题的解法是非常有帮助的。

请详细解析以下代码,罗列出其中涉及到的所有知识,并讲解每一行代码的由来:请详细解析以下代码,罗列出其中涉及到的所有知识,并讲解每一行代码的由来:#include <stdio.h> #include <stdlib.h> typedef struct tree////定义二叉树结点 { int data; struct tree* lchild; struct tree* rchild; }tree; typedef struct queue//定义队列结点 { tree* data; struct queue* next; }queue; typedef struct line//定义队列 { queue* front; queue* rear; }line; void rule(line* queue)//初始化队列 {queue->front=queue->rear=NULL;} int empty(line* queue)//判断队列是否为空 {return queue->front==NULL;} void in(line* queue, tree* node)//入队 { queue* qnode=(queue*)malloc(sizeof(queue)); qnode->data=node; qnode->next=NULL; if (queue->rear==NULL) {queue->front=queue->rear = qnode;} else { queue->rear->next = qnode; queue->rear = qnode; } } tree* out(line* queue)//出队 { if (queue->front==NULL) {return NULL;} else { tree* node = queue->front->data; queue* temp = queue->front; queue->front = queue->front->next; if(queue->front == NULL) {queue->rear = NULL;} free(temp); return node; } } void levelorder(tree* root)//按层次遍历二叉树 { if (root==NULL) {return;} line queue; rule(&queue); in(&queue,root); while(!empty(&queue)) { tree* node=out(&queue); printf("%d ",node->data); if(node->lchild != NULL) {in(&queue, node->lchild);} if(node->rchild != NULL) {in(&queue, node->rchild);} } } tree* create(int data)//创建二叉树结点 { tree* node=(tree*)malloc(sizeof(tree)); node->data=data; node->lchild=NULL; node->rchild=NULL; return node; } tree* create()//创建二叉树 { tree* root=create(1); root->lchild=create(2); root->rchild=create(3); root->lchild->lchild=create(4); root->lchild->rchild=create(5); root->rchild->lchild=create(6); root->rchild->rchild=create(7); return root; } int main() { tree* root=create(); printf("按层次遍历结果为: "); levelorder(root); return 0; }

2023-05-24 上传