A--1-数据结构(2)--二叉树及递归
B-二叉树专题
xmind笔记链接:
http://note.youdao.com/noteshare?id=65769eb1a96a653e193def55f1a7a7f0
题目
- 三种遍历(递归)
- 三种遍历(非递归)(栈)
- 层次遍历(节点/层)(队列)
- 二叉树最大深度(递归套路)
- 判断平衡二叉树(递归套路)
- 判断二叉搜索树(递归套路)
- 镜像二叉树(递归)
- 对称二叉树(递归)
- 二叉树中和为某一值的路径(递归回溯)
- 重建二叉树 (递归)
- 二叉树的最低公共祖先(递归套路)
- 二叉搜索树的最低公共祖先
- 二叉搜索树的第k大节点
- 合并二叉树(递归)
- 判断完全二叉树
- 二叉树的序列化
- 子树判断
二叉树的遍历
实际上二叉树的前序中序后序的遍历的递归方法很简单.
题目1 层次遍历1
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
queue<TreeNode*> q;
vector<int> v;
if ( ! root )
return v;
q.push(root);
while ( !q.empty() )
{
TreeNode* tmp = q.front();
q.pop();
if( tmp->left )
q.push(tmp->left);
if ( tmp->right)
q.push(tmp->right);
v.push_back(tmp->val);
}
return v;
}
};
二叉树的递归套路
题目1 求二叉树的深度
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
return process(root);
}
int process(TreeNode* x)
{
if ( x == nullptr)
return 0;
int leftdepth = process(x->left);
int rightdepth = process (x->right);
return max( leftdepth , rightdepth ) + 1;
if (x->right == nullptr && x->left == nullptr)
return 1;
}
};
题目2 判断一棵树是否为平衡二叉树
- 要注意判断条件,空树的情况下,要返回
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
class Info {
public:
bool isBalance ;
int depth;
Info (bool is , int dep) {
isBalance = is ;
depth = dep;
}
};
bool isBalanced(TreeNode* root) {
Info ans = process(root);
return ans.isBalance;
}
Info process( TreeNode* x)
{
// 定义当前树的信息
Info info = Info( false, 0 );
// 树空的时候,深度0,是平衡二叉树
// 这里不return会出错的,因为空的树,就不能由左子树右子树了
if ( x == nullptr)
{
info.isBalance = true;
info.depth = 0;
return info;
}
// 从左右子树得到信息
Info leftInfo = process( x->left );
Info rightInfo = process( x->right );
// 根据左右子树的信息,给出树x的信息(深度///是否为平衡二叉树)
info.depth = max (leftInfo.depth , rightInfo.depth)+1 ;
if ( leftInfo.isBalance == false || rightInfo.isBalance == false)
{
info.isBalance = false;
}
if ( (leftInfo.isBalance == true && rightInfo.isBalance == true)
&& abs(leftInfo.depth - rightInfo.depth) < 2 )
{
info.isBalance = true;
}
return info;
}
};
题目3 判断是否为搜索二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
class Info{
public:
int maxValue;
int minValue;
bool isBST;
Info (int ma , int mi , bool is ){
maxValue = ma;
minValue = mi;
isBST = is;
}
};
bool isValidBST(TreeNode* root) {
Info ans = process(root);
return ans.isBST;
}
Info process(TreeNode* x)
{
Info info = Info( 0 , 0 , false );
if ( x == nullptr)
{
info.isBST = true;
info.maxValue = 0;
info.minValue = 0;
return info;
}
Info leftInfo = process ( x->left ) ;
Info rightInfo = process (x->right);
// 如果左子树或者右子树不是搜索二叉树,那就不用再往下看了,直接返回.
if ( leftInfo.isBST == false || rightInfo.isBST == false )
{
return info;
}
/*
下面的代码罗列了所有当前树是搜索二叉树的可能情况
1. 叶子节点
2. 只有左孩子
3. 只有右孩子
4. 左右孩子都有
以上四种情况只能发生一种
*/
// 1 当前节点既没有左子树也没有右子树
if ( x->left == nullptr && x->right == nullptr)
{
info.maxValue = x->val ;
info.minValue = x->val;
info.isBST = true;
return info;
}
// 2 只有右子树
if( (x->left == nullptr && x->right) && rightInfo.minValue > x->val )
{
info.maxValue = max( rightInfo.maxValue , x->val);
info.minValue = x->val;
info.isBST = true;
return info;
}
// 3 只有左子树
if( (x->left && x->right == nullptr) && leftInfo.maxValue < x->val)
{
info.minValue = min( leftInfo.minValue , x->val);
info.maxValue = x->val;
info.isBST = true;
return info;
}
// 4 当前节点的左子树和右子树都存在
if (x->left && x->right && x->val > leftInfo.maxValue && x->val < rightInfo.minValue)
{
info.isBST = true;
info.minValue = leftInfo.minValue;
info.maxValue = rightInfo.maxValue;
return info;
}
return info;
}
};
题目4 镜像二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
process(root);
return root;
}
void process (TreeNode* x)
{
if ( ! x )
return;
process(x->left);
process(x->right);
if ( x->right && x->left )
{
TreeNode* tmp = x->right;
x->right = x->left;
x->left = tmp;
return ;
}
if ( x->right == nullptr && x->left )
{
x->right = x->left;
x->left = nullptr;
return ;
}
if ( x->right && x->left == nullptr)
{
x->left = x->right;
x->right = nullptr;
return ;
}
}
};
题目5 是否为对称二叉树
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if ( !root )
{
return true;
}
return process(root->left,root->right);
}
bool process(TreeNode* x , TreeNode* y)
{
if ( x == nullptr && y == nullptr )
{
return true;
}
if ( x == nullptr || y == nullptr)
{
return false;
}
if ( x->val != y->val )
{
return false;
}
return process (x->left , y->right) && process(x->right,y->left) ;
}
};
题目6 二叉树中和为某一值的路径(递归回溯)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> ans;
vector<int> path;
if(root == nullptr)
{
return ans ;
}
process(root , sum , path , ans );
return ans;
}
void process( TreeNode* x , int sum , vector<int>& path ,
vector<vector<int>>& ans )
{
if( sum == x->val && ( x->left == nullptr && x->right == nullptr))
{
path.push_back(x->val);
ans.push_back( path );
path.pop_back();
return ;
}
path.push_back(x->val);
sum = sum - x->val;
if ( x->left )
process(x->left , sum , path, ans );
if ( x->right )
process(x->right , sum , path , ans);
path.pop_back();
}
};
题目 7 重建二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return process(preorder,inorder);
}
TreeNode* process(vector<int>& preorder , vector<int>& inorder)
{
if (preorder.size() == 0 || inorder.size() == 0)
{
return nullptr;
}
TreeNode* x = new TreeNode(preorder[0]);
int pos = 0;
for ( int i = 0 ; i < inorder.size(); i ++)
{
if( inorder[i] == x->val)
{
pos = i ;
break;
}
}
int LeftLen = pos ;
vector<int> preorderLeft ( preorder.begin()+1 , preorder.begin()+1 + LeftLen);
vector<int> preorderRight ( preorder.begin() + 1 + LeftLen, preorder.end());
vector<int> inorderLeft (inorder.begin() , inorder.begin() + LeftLen );
vector<int> inorderRight(inorder.begin() + LeftLen + 1 , inorder.end() );
x->left = process (preorderLeft , inorderLeft );
x->right = process (preorderRight , inorderRight);
return x;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return build(inorder,preorder,0,inorder.size()-1,0,preorder.size()-1);
}
TreeNode* build(vector<int>& inorder,vector<int>& preorder, int is,int ie,int ps,int pe)
{
if(inorder.size()==0 || preorder.size()==0)
{
return NULL;
}
int ll = 0 ;
int rl = 0 ;
TreeNode* ans = new TreeNode(preorder[ps]);
for(int i = is; i<= ie; i++)
{
if(preorder[ps]==inorder[i])
{
ll = i - is ;
rl = ie - i;
}
}
if ( ll > 0 )
{
ans->left = build (inorder,preorder,is,is+ll-1,ps+1 ,ps+ll );
}
if ( rl > 0 )
{
ans->right = build(inorder,preorder,ie-rl+1,ie,pe-rl+1,pe);
}
return ans;
}
};
题目 8 二叉树的最低公共祖先
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
class Info {
public:
TreeNode* ans;
bool isFindP;
bool isFindQ;
Info( bool b , bool c , TreeNode* k)
{
ans = k ;
isFindP = b ;
isFindQ = c;
}
};
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
Info information = process( root , p , q );
return information.ans;
}
Info process( TreeNode* x , TreeNode* p , TreeNode* q)
{
Info info = Info ( false , false , nullptr ) ;
if (x == nullptr )
{
return info ;
}
Info leftinfo = process(x->left , p ,q );
Info rightinfo = process(x->right , p , q);
// ① 如果左右子树找到了低共,返回左右子树的低共
if ( leftinfo.ans != nullptr )
{
return Info ( true , true , leftinfo.ans );
}
if ( rightinfo.ans != nullptr )
{
return Info ( true , true , rightinfo.ans );
}
// ② p 和 q 分布在x的左右子树上, x 是低共
if ( ( leftinfo.isFindP == true && rightinfo.isFindQ == true )
|| (leftinfo.isFindQ == true && rightinfo.isFindP == true) )
{
return Info ( true , true , x );
}
// ③ x的左右子树上有 p 和 q 的一个
// ③-① x 的左右子树里有q(p), 且 x 是另一个p(q), x也是低共
// ③-② x 的左右子树里有q(p), 但是 x 不是p(q)
bool findp = x==p;
bool findq = x==q;
if ( leftinfo.isFindP || rightinfo.isFindP )
{
if (findq){
return Info ( true , true , x );
}else{
return Info ( true , false , nullptr );
}
}
if ( leftinfo.isFindQ || rightinfo.isFindQ )
{
if (findp){
return Info ( true , true , x );
}else{
return Info ( false , true , nullptr );
}
}
// ④ x的左右子树里没有 q ,也没有 p
return Info( findp , findq , nullptr ) ;
}
};
题目9 二叉搜索树的最低公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(p->val<root->val&&q->val<root->val)
return lowestCommonAncestor(root->left,p,q);
if(p->val>root->val&&q->val>root->val)
return lowestCommonAncestor(root->right,p,q);
return root;
}
};
题目10 二叉搜索树的第k大节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthLargest(TreeNode* root, int k) {
vector<int> vec;
process( root, vec);
return vec[k-1];
}
void process( TreeNode* x , vector<int>& order)
{
if ( x == nullptr )
return ;
if (x->right)
process(x->right , order);
order.push_back(x->val);
if (x->left)
process(x->left, order);
}
};
本文来自博客园,作者:longlongban,转载请注明原文链接:https://www.cnblogs.com/jiangxinyu1/p/12407649.html
简单学习分享,如有错误欢迎指正