前序遍历
前序遍历伪代码:
void prevorderTraverse(TreeNode* root)
{
if (root == NULL)
return;
// 前序遍历代码
prevorderTraverse(root->left);//递归左子树
prevorderTraverse(root->right);//递归右子树
}
LeetCode297-二叉树的序列化与反序列化:输入一棵二叉树的根节点 root,要求你实现一个类,用serialize方法将二叉树序列化成字符串,用deserialize方法将序列化的字符串反序列化成二叉树
class Codec {
public:
int index=0;
//序列化
string serialize(TreeNode* root)
{
string str;
PreOrderTraverse(root,str);//前序遍历
return str;
}
//前序遍历
//将二叉树序列化为字符串,val之间用,隔开
//空节点用#表示
void PreOrderTraverse(TreeNode* root,string& str)
{
if(!root)
{
str+="#,";
return;
}
str=str+to_string(root->val)+",";//整型转换为字符串
PreOrderTraverse(root->left,str);//遍历左子树
PreOrderTraverse(root->right,str);//遍历右子树
}
//反序列化
TreeNode* deserialize(string str)
{
vector<string> vec;
split(str,vec);//按,进行字符串切分
return createTree(vec);//创建二叉树
}
//根据前序遍历结果创建一棵二叉树
TreeNode* createTree(vector<string> vec)
{
if(index==vec.size())
return NULL;
TreeNode* root=NULL;
string str=vec[index++];
if (str != "#")
{
int val=atoi(str.c_str());//字符串转为整型
root = new TreeNode(val);
root->left = createTree(vec);//创建左子树
root->right = createTree(vec);//创建右子树
}
return root;
}
//切分字符串
void split(string str,vector<string>& vec)
{
int nPos = str.find( "," );
string strTmp;
while( nPos > 0 )
{
strTmp = str.substr( 0, nPos );//字串
vec.push_back( strTmp );
str.erase( 0, nPos+1 );//删除子串
nPos = str.find( "," );
}
return;
}
};
中序遍历
中序遍历伪代码:
void inorderTraverse(TreeNode* root)
{
if (root == NULL)
return;
inorderTraverse(root->left);//递归左子树
// 中序遍历代码
inorderTraverse(root->right);//递归右子树
}
//中序遍历 //扩展的中序遍历结果不能唯一确定一棵二叉树 // 1 2 // / / // 2 3 1 // / // 3 //扩展的中序遍历均为#3#2#1#
后序遍历
后序遍历伪代码:
void postorderTraverse(TreeNode* root)
{
if (root == NULL)
return;
postorderTraverse(root->left);//递归左子树
postorderTraverse(root->right);//递归右子树
// 后序遍历代码
}
LeetCode297-二叉树的序列化与反序列化:输入一棵二叉树的根节点 root,要求你实现一个类,用serialize方法将二叉树序列化成字符串,用deserialize方法将序列化的字符串反序列化成二叉树
//后序遍历
class Codec
{
public:
int index=0;
//序列化
string serialize(TreeNode* root)
{
string str;
PostOrderTraverse(str,root);//后序遍历
return str;
}
//后序遍历
void PostOrderTraverse(string& str,TreeNode* root)
{
if(!root)
{
str+="#,";
return;
}
PostOrderTraverse(str,root->left);//遍历左子树
PostOrderTraverse(str,root->right);//遍历右子树
str=str+to_string(root->val)+",";
}
//反序列化
TreeNode* deserialize(string str)
{
vector<string> vec;
split(vec,str);
index=vec.size()-1;
return CreateTree(vec);
}
//根据扩展的后序遍历结果创建二叉树
//后序遍历的特点:生成树的字符串的最后一个字符,代表的就是它的根结点,倒数第二个就是它的右孩子
//从字符串后面开始推,按照根结点 -> 右结点 ->左节点 的顺序就能通过递归构造出一棵二叉树了
TreeNode* CreateTree(vector<string> vec)
{
if(index<0)
return NULL;
TreeNode* root=NULL;
string str=vec[index--];
if(str!="#")
{
int val=atoi(str.c_str());
root=new TreeNode(val);
root->right=CreateTree(vec);//创建右子树
root->left=CreateTree(vec);//创建左子树
}
return root;
}
//切分字符串
void split(vector<string>& vec,string str)
{
int pos=str.find(",");
string strTemp;
while(pos>0)
{
strTemp=str.substr(0,pos);
vec.push_back(strTemp);
str.erase(0,pos+1);
pos=str.find(",");
}
return;
}
};
层序遍历
层序遍历伪代码:
void traverse(TreeNode* root)
{
if (root == NULL)
return;
// 初始化队列,将 root 加入队列
queue<TreeNode*> queue;
queue.push(root);
while (!q.empty())
{
TreeNode* cur = queue.front();
queue.pop();
//层级遍历代码
if (cur->left != NULL)
q.push(cur->left);
if (cur->right != NULL)
q.push(cur->right);
}
}
LeetCode297-二叉树的序列化与反序列化:输入一棵二叉树的根节点 root,要求你实现一个类,用serialize方法将二叉树序列化成字符串,用deserialize方法将序列化的字符串反序列化成二叉树(仅仅适用于完全二叉树)
//层序遍历,只适用于完全二叉树
class Codec
{
public:
//序列化
string serialize(TreeNode* root)
{
string str;
LevelOrderTraverse(str,root);//层序遍历
cout<<str<<endl;
return str;
}
void LevelOrderTraverse(string& str,TreeNode* root)
{
if(!root)
return;
queue<TreeNode*> que;
que.push(root);
while(!que.empty())
{
TreeNode* current=que.front();
que.pop();
str=str+to_string(current->val)+",";
if(current->left!=NULL)
que.push(current->left);
if(current->right!=NULL)
que.push(current->right);
}
}
//反序列化
TreeNode* deserialize(string str)
{
vector<string> vec;
split(vec,str);
int index=0;
return CreateTree(vec,index);
}
//根据扩展的层序遍历结果创建二叉树
TreeNode* CreateTree(vector<string> vec,int index)
{
if(index>=vec.size())
return NULL;
TreeNode* root=NULL;
string str=vec[index];
int val=atoi(str.c_str());
root=new TreeNode(val);
root->left=CreateTree(vec,2*index+1);
root->right=CreateTree(vec,2*index+2);
return root;
}
//切分字符串
void split(vector<string>& vec,string str)
{
int pos=str.find(",");
string strTemp;
while(pos>0)
{
strTemp=str.substr(0,pos);
vec.push_back(strTemp);
str.erase(0,pos+1);
pos=str.find(",");
}
return;
}
};
根据两种遍历结果确定二叉树
伪代码:
TreeNode* CreateTree(遍历结果1,遍历结果2)
{
if(遍历结果为空)
return NULL;
TreeNode* root=new TreeNode(根节点值);
if(遍历结果大小为1)
return root;
else
{
//根据根节点将遍历结果划分为
//左子树的遍历结果1,左子树的遍历结果2
//右子树的遍历结果1,右子树的遍历结果2
root->left=CreateTree(左子树的遍历结果1,左子树的遍历结果2);
root->right=CreateTree(右子树的遍历结果1,右子树的遍历结果2);
}
return root;
}
LeetCode105-前序遍历+中序遍历确定一棵二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
if(preorder.empty()||inorder.empty()||preorder.size()!=inorder.size())
return NULL;
return CreateTree(preorder,inorder);
}
TreeNode* CreateTree(vector<int> preorder,vector<int> inorder)
{
if(preorder.empty())
return NULL;
TreeNode* root=new TreeNode(preorder[0]);
if(preorder.size()==1)
return root;
else
{
int valTemp=preorder[0];
auto pos=find(inorder.begin(),inorder.end(),valTemp);
int i=pos-inorder.begin();
vector<int> prevLeft{preorder.begin()+1,preorder.begin()+1+i};//左子树的前序遍历
vector<int> prevRight{preorder.begin()+1+i,preorder.end()};//右子树的前序遍历
vector<int> inLeft{inorder.begin(),inorder.begin()+i};//左子树的中序遍历
vector<int> inRight{inorder.begin()+i+1,inorder.end()};//右子树的中序遍历
root->left=CreateTree(prevLeft,inLeft);//创建左子树
root->right=CreateTree(prevRight,inRight);//创建右子树
}
return root;
}
};
LeetCode889-前序遍历+后序遍历确定一棵二叉树的任意一种情况
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* constructFromPrePost(vector<int>& pre, vector<int>& post)
{
if(pre.empty()||post.empty()||pre.size()!=post.size())
return NULL;
return CreatTree(pre,post);
}
//前序遍历的第一个元素和后序遍历的最后一个元素为根节点
//前序遍历的第二个元素为左子树的根节点
//后序遍历的倒数第二个元素为右子树的根节点
//根据左右子树根结点的值可以将整个遍历结果切分为左/右子树的前/后序遍历
TreeNode* CreatTree(vector<int>& pre,vector<int>& post)
{
TreeNode* root=NULL;
if(pre.empty())
return NULL;
root=new TreeNode(pre[0]);
if(pre.size()==1)
return root;
else
{
//valLeft左子树根结点的值
int valLeft=pre[1];
auto pos=find(post.begin(),post.end(),valLeft);
int i=pos-post.begin()+1;//左子树有i个元素
vector<int> preLeft{pre.begin()+1,pre.begin()+1+i};//左子树的前序遍历
vector<int> postLeft{post.begin(),post.begin()+i};//左子树的后序遍历
vector<int> preRight{pre.begin()+1+i,pre.end()};//右子树的前序遍历
vector<int> postRight{post.begin()+i,post.end()-1};//右子树的后序遍历
//递归创建左右子树
root->left=CreatTree(preLeft,postLeft);
root->right=CreatTree(preRight,postRight);
}
return root;
}
};
LeetCode106-中序遍历+后序遍历确定一棵二叉树
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) { if(inorder.empty()||postorder.empty()||inorder.size()!=postorder.size()) return NULL; return CreateTree(inorder,postorder); } TreeNode* CreateTree(vector<int> inorder,vector<int> postorder) { if(inorder.empty()) return NULL; TreeNode* root=new TreeNode(postorder[postorder.size()-1]); if(inorder.size()==1) return root; else { int valTemp=postorder[postorder.size()-1]; auto pos=find(inorder.begin(),inorder.end(),valTemp); int i=pos-inorder.begin(); vector<int> inLeft{inorder.begin(),inorder.begin()+i}; vector<int> inRight{inorder.begin()+i+1,inorder.end()}; vector<int> postLeft{postorder.begin(),postorder.begin()+i}; vector<int> postRight{postorder.begin()+i,postorder.end()-1}; root->left=CreateTree(inLeft,postLeft); root->right=CreateTree(inRight,postRight); } return root; } };