二叉树题目总结归纳:
二叉树结构:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
class TreeNode{
public:
int val;
TreeNode* left;
TreeNode* right;
TreeNode(x): val(x), left(NULL), right(NULL)
{
}
};
1求二叉树的最大深度
// v1 深度遍历
int find_max_depth_v1(TreeNode* root)
{
if(!root)
return 0;
int left = find_max_depth_v1(root->left);
int right = find_max_depth_v1(root->right);
return 1 + (left > right ? left : right);
}
// v2 宽度优先
int find_max_depth_v2(TreeNode* root)
{
if(!root)
return 0;
queue<TreeNode*> q;
q.push(root);
int depth = 0;
while(!q.empty())
{
depth ++;
for(int i = 0; i < q.size(); i++)
{
TreeNode* pNode = q.front();
q.pop();
if(pNode->left)
q.push(pNode->left);
if(pNode->right)
q.push(pNode->right);
}
}
return depth;
}
2.求二叉树的最小深度
// v1 深度优先
//这里与最大深度不同的地方是,需要考虑二叉树仅有一边子树的情况,
//若直接套用最大子树的思路,取左右子树中的最小值,那么最小值永远是0
int find_min_depth_v1(TreeNode* root)
{
if(!root)
return 0;
if(!root->left)
return 1 + find_min_depth_v1(root->right);
if(!root->right)
return 1 + find_min_depth_v1(root->left);
return 1 + (left < right ? left : right);
}
// v2 宽度优先
int find_min_depth_v2(TreeNode* root)
{
if(!root)
return 0;
queue<TreeNode*> q;
q.push(root);
int depth = 0;
while(!q.empty())
{
depth ++;
for(int i = 0; i < q.size(); i++)
{
TreeNode* pNode = q.front();
q.pop();
if(!pNode->left && !pNode->right)
return depth;
if(pNode->left)
q.push(pNode->left);
if(pNode->right)
q.push(pNode->right);
}
}
return depth;
}
3.求二叉树中节点的个数
int get_num_node(TreeNode* root)
{
if(!root)
return 0;
int left = get_num_node(root->left);
int right = get_num_node(root->right);
return left + right + 1;
}
4.求二叉树中叶子节点的个数
int get_leaf_node(TreeNode* root)
{
if(!root)
return 0;
if(!root->left && !root->right)
return 1;
int left = get_leaf_node(root->left);
int right = get_leaf_node(root->right);
return left + right;
}
5.求二叉树中第 k 层节点的个数
int get_kth_node(TreeNode* root, int k)
{
if(!root || k < 1)
return 0;
if(k == 1)
return 1;
int left = get_kth_node(root->left, k-1);
int right = get_kth_node(root->right, k-1);
return left + right;
}
6.二叉树的第K大个节点
//中序遍历
TreeNode* kthNode(TreeNode* root, int k)
{
if(!root || k < 1)
return NULL;
return kthNodeCore();
}
TreeNode* kthNodeCore(TreeNode* root)
{
TreeNode* res = NULL;
if(root->left)
res = kthNodeCore(root->left);
if(!res)
{
if(k == 1)
res = root;
k --;
}
if(!res && root->right)
res = kthNodeCore(root->right);
return res;
}
7.判断二叉树是否是平衡二叉树
bool IsBalanceTree(TreeNode* root)
{
if(!root)
return true;
return max_depth(root) != -1;
}
int max_depth(TreeNode* root)
{
if(!root)
return 0;
int left = max_depth(root->left);
int right = max_depth(root->right);
if(left == -1 || right == -1 || abs(left - right) > 1)
return -1;
return 1 + (left > right ? left : right);
}
8.判断二叉树是否是完全二叉树
/判断一棵树是否是完全二叉树,首先要知道什仫是完全二叉树?
//完全二叉树就是除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。
bool IsCompleteTree(TreeNode* root)
{
if(!root)
return false;
queue<TreeNode*> q;
q.push(root);
TreeNode* cur = q.front();
while(cur)
{
q.push(root->left);
q.push(root->right);
q.pop();
cur = q.front();
}
while(!q.empty())
{
if(q.front())
return false;
q.pop();
}
return true;
}
9.两个二叉树是否完全相同
// 前序遍历
bool IsSameTree(TreeNode* root1, TreeNode* root2)
{
if(!root1 && !root2)
return true;
if(!root1 || !root2)
return false;
if(root1->val != root2->val)
return false;
bool left = IsSameTree(root1->left, root2->left);
bool right = IsSameTree(root1->right, root2->right);
return left && right;
}
10.两个二叉树是否互为镜像
bool IsMirrorTree(TreeNode* root1, TreeNode* root2)
{
if(!root1 && !root2)
return true;
if(!root1 || !root2)
return false;
if(root1->val != root2->val)
return false;
return IsMirrorTree(root1->left, root2->right) && \
IsMirrorTree(root1->right, root2->left);
}
11.翻转或者镜像二叉树
void MirrorTree(TreeNode* root)
{
if(!root)
return ;
if(!root->left && !root->right)
return ;
TreeNode* tmp = root->left;
root->left = root->right;
root->right = tmp;
MirrorTree(root->left);
MirrorTree(root->right);
}
12.求两个二叉树的最低公共祖先节点
// 利用二叉树的递增属性
TreeNode* getLastCommonParent(TreeNode* root, TreeNode* node1, TreeNode* node2)
{
if(!root || !node1 || !node2)
return NULL;
if(finNode(root->left, node1))
{
if(findNode(root->right, node2))
return root;
else
return getLastCommonParent(root->left, node1, node2);
}
else{
if(findNode(root->left, node2))
return root;
else
return getLastCommonParent(root->right, node1, node2);
}
}
// 节点是否在子树内
bool findNode(TreeNode* root, TreeNode* node)
{
if(!root || !node)
return false;
if(root->val == node->val && root->left == node->left \
&& root->right == node->right)
return true;
bool res = findNode(root->left);
if(!res)
res = findNode(root->right);
return res;
}
13.前序遍历
vector<int> preOrder(TreeNode* root)
{
vector<int> result;
if(!root)
return result;
preOrderCore(root, result);
return result;
}
void preOrderCore(TreeNode* root, vector<int>& result)
{
if(!root)
return ;
result.push_back(root->eval);
if(root->left)
preOrderCore(root->left, result);
if(root->left)
preOrderCore(root->right, result);
}
14.中序遍历
vector<int> midOrder(TreeNode* root)
{
vector<int> result;
if(!root)
return result;
midOrderCore(root, result);
return result;
}
void midOrderCore(TreeNode* root, vector<int>& result)
{
if(root->left)
midOrderCore(root->left, result);
if(!root)
result.push_back(root->val);
if(root->right)
midOrderCore(root->right, result);
}
15.后序遍历
vector<int> postOrder(TreeNode* root)
{
vector<int> result;
if(!root)
return result;
postOrderCore(root, result);
return result;
}
void postOrderCore(TreeNode* root, vector<int>& result)
{
if(root->left)
postOrderCore(root->left, result);
if(root->right)
postOrderCore(root->right, result);
if(!root)
result.push_back(root->val);
}
16.输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树
TreeNode* reConstructTree(vector<int> pre, vector<int> vin)
{
int len1 = pre.size();
int len2 = vin.size();
if(pre.empty() || vin.empty() || len1 == len2)
return NULL;
return reConstructTreeCore(pre, vin, 0, len1 - 1, 0, len2 - 1);
}
TreeNode* reConstructTreeCore(vector<int> pre, vector<int> vin, int begin1, int end1, \
int begin2, int end2)
{
int val = pre[begin1];
TreeNode* root = new TreeNode(val);
if(begin1 == end1)
return root;
int ind = begin2;
while(vin[ind] != val)
ind ++;
if(ind > begin2)
root->left = reConstructTreeCore(pre, vin, begin1 + 1, begin1 + ind - begin2, \
begin2, ind - 1);
if(ind < end2)
root->right = reConstructTreeCore(pre, vin, begin1 + ind - begin2 + 1, end1, \
ind + 1, end2);
return root;
}
未完待续。。。20190611晚!