0前言
- 7 重建二叉树(递归)
- 8 二叉树的下一节点
- 26 树的子结构(递归)
- 27 二叉树的镜像(递归)
- 28 对称的二叉树(递归)
- 32 从上到下打印二叉树(广度遍历)
- 33 二叉搜索树的后序遍历序列(递归)
- 34 二叉树中和为某一值的路径(深度遍历、前序遍历首先访问根节点)
- 37 序列化二叉树(前序遍历)、反序列化二叉树
- 55 二叉树的深度
7 重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
/**
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {//返回节点指针
if(pre.empty()||vin.empty())
return NULL;
//0. 创建需要返回的节点
TreeNode* pNode=new TreeNode(pre[0]);
//1. 根在中序遍历位置
int root=pre[0];
int left_length=0;
while(vin[left_length]!=root){
left_length++;
}
//2. 递归左子树、右子树
vector<int> left_pre,right_pre,left_vin,right_vin;
for(int i=0;i<left_length;i++){
left_pre.push_back(pre[i+1]);//用push_back()添加元素
left_vin.push_back(vin[i]);
}
for(int j=left_length+1;j<pre.size();j++){
right_pre.push_back(pre[j]);
right_vin.push_back(vin[j]);
}
pNode->left=reConstructBinaryTree(left_pre,left_vin);
pNode->right=reConstructBinaryTree(right_pre,right_vin);
return pNode;
}
};
注意:
1、步骤0 创建新节点换种方式是错误的:
TreeNode *pNode;
pNode->val=pre[0];
pNode->left=NULL;
pNode->right=NULL;
第一句只是定义了个野指针,指针地址是随机的,不会自动分配内存。第二句运行已经在非法访问其他内存了,可能会造成其他程序内存破坏,导致异常死机。
正确做法:TreeNode* pNode=new TreeNode(pre[0]); //创建新节点时,指明数值。
2、vector添加元素用push_back();不能直接用=赋值
8 二叉树的下一节点
题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==nullptr)
return nullptr;
TreeLinkNode* pNext=nullptr;
//1. 有右子树,右子树最左节点
if(pNode->right!=nullptr){
TreeLinkNode* pright=pNode->right;
while(pright->left!=nullptr){
pright=pright->left;//更新
}
pNext=pright;
}
//2. 无右子树,且为左子树,父节点
//3. 无右子树,且为右子树,溯源至根父节点
else if(pNode->next!=nullptr){
TreeLinkNode* pCurrent=pNode;
TreeLinkNode* pParent=pNode->next;
while(pParent!=nullptr&&pParent->right==pCurren