/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
1.重建二叉樹(前序、中序)
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
int n1 = pre.size();
int n2 = vin.size();
if(n1 != n2 || n1 <= 0)
{
return NULL;
}
TreeNode *root = new TreeNode(pre[0]);
int pos = 0;
for(;pos<n2;++pos)
{
if(vin[pos] == pre[0])
break;
}
if(pos == n2) exit(-1);
vector<int> pre_left,vin_left,pre_right,vin_right;
for(int i=0;i < n1;++i)
{
if(i<pos)
{
pre_left.push_back(pre[i+1]);
vin_left.push_back(vin[i]);
}
else if(i>pos)
{
pre_right.push_back(pre[i]);
vin_right.push_back(vin[i]);
}
}
root->left = reConstructBinaryTree(pre_left,vin_left);
root->right = reConstructBinaryTree(pre_right,vin_right);
return root;
}
{
if(vin[pos] == pre[0])
break;
}
if(pos == n2) exit(-1);
vector<int> pre_left,vin_left,pre_right,vin_right;
for(int i=0;i < n1;++i)
{
if(i<pos)
{
pre_left.push_back(pre[i+1]);
vin_left.push_back(vin[i]);
}
else if(i>pos)
{
pre_right.push_back(pre[i]);
vin_right.push_back(vin[i]);
}
}
root->left = reConstructBinaryTree(pre_left,vin_left);
root->right = reConstructBinaryTree(pre_right,vin_right);
return root;
}
中序、後序重建二叉樹,與前序、中序重建二叉樹思想一致。利用前序或者後序遍歷根結點的位置特性,找到中序遍歷序列中根結點的位置,進而將中序遍歷序、前序或者後序列分成左子樹、根結點、右子樹,左右子樹進行遞歸。
先序、後序無法重建二叉樹。
2.層序遍歷二叉樹
vector<int> PrintFromTopToBottom(TreeNode* root) {
vector<TreeNode *> tree;
vector<int> res;
if(root == NULL)
return res;
tree.push_back(root);
TreeNode *pnode = NULL;
while(tree.size())
{
pnode = tree.front();
tree.erase(tree.begin());
res.push_back(pnode->val);
if(pnode->left)
tree.push_back(pnode->left);
if(pnode->right)
tree.push_back(pnode->right);
}
return res;
}
};
利用隊列先進先出的思想,首先將根結點入進去,出一個結點,如果左/右子樹不爲NULL,將它的左/右子節點入進去。
3.二叉樹的深度
int TreeDepth(TreeNode* pRoot)
{
if(pRoot == NULL)
return 0;
else
{
int left_depth = TreeDepth(pRoot->left);
int rigth_depth = TreeDepth(pRoot->right);
return left_depth > rigth_depth ? left_depth +1 : rigth_depth+1;
}
}
利用遞歸的思想,二叉樹的深度爲左右子樹深度最大值+1。
4.二叉樹是否是平衡二叉樹
//一個節點被重複遍歷多次
int TreeDepth(TreeNode* pRoot)
{
if(pRoot == NULL)
return 0;
else
{
int left_depth = TreeDepth(pRoot->left);
int rigth_depth = TreeDepth(pRoot->right);
return left_depth > rigth_depth ? left_depth +1 : rigth_depth+1;
}
}
bool IsBalanced_Solution(TreeNode* pRoot) {
return (pRoot == NULL) ||
( abs(TreeDepth(pRoot->left)-TreeDepth(pRoot->right)) <= 1 &&
IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right) );
}
結合求深度的方法,對二叉樹進行遞歸判斷,優點是思想容易理解,代碼簡潔。缺點是一個節點被重複遍歷多次。
改進:一遍進行後序遍歷,一邊進行判斷。此時每個結點只遍歷一次。
bool IsBalanced(TreeNode *root, int & dep){
if(root == NULL){
return true;
}
int left = 0;
int right = 0;
if(IsBalanced(root->left,left) && IsBalanced(root->right, right)){
int dif = left - right;
if(dif<-1 || dif >1)
return false;
dep = (left > right ? left : right) + 1;
return true;
}
return false;
}
bool IsBalanced_Solution(TreeNode* pRoot) {
int dep = 0;
return IsBalanced(pRoot, dep);
}