# 剑指offer（四）树

## 面试题6：重建二叉树

TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
int length = pre.size();
return constructCore(pre,vin,0,length-1,0,length-1);
}
TreeNode* constructCore(vector<int> pre,vector<int> vin, int preL, int preR, int inL, int inR){
int rootValue = pre[preL];
TreeNode* root = new TreeNode(rootValue);
int rootInOrder = inL;
while(rootInOrder <= inR && vin[rootInOrder] != rootValue)
rootInOrder++;
int leftLength = rootInOrder - inL;
if(leftLength > 0){
root->left = constructCore(pre,vin,preL+1,preL+leftLength,inL,rootInOrder-1);
}
if(leftLength < preR-preL){
root->right = constructCore(pre,vin,preL+leftLength+1,preR,rootInOrder+1,inR);
}
return root;
}

## 面试题18：树的子结构

class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
bool result = false;
if(pRoot1 != NULL && pRoot2 != NULL){
if(pRoot1->val == pRoot2->val)
result = DoesTree1HasTree2(pRoot1, pRoot2);
if(!result)
result = HasSubtree(pRoot1->left, pRoot2);
if(!result)
result = HasSubtree(pRoot1->right, pRoot2);
}
return result;
}
bool DoesTree1HasTree2(TreeNode* pRoot1, TreeNode* pRoot2){
if(pRoot2 == NULL)
return true;
if(pRoot1 == NULL)
return false;
if(pRoot1->val != pRoot2->val)
return false;
return DoesTree1HasTree2(pRoot1->left,pRoot2->left) && DoesTree1HasTree2(pRoot1->right,pRoot2->right);
}
};

## 面试题19：二叉树的镜像

class Solution {
public:
void Mirror(TreeNode *pRoot) {
if(pRoot==NULL)
return;
if(pRoot->left==NULL && pRoot->right==NULL)
return;
TreeNode *tmp = pRoot->right;
pRoot->right = pRoot->left;
pRoot->left = tmp;
if(pRoot->left != NULL)
Mirror(pRoot->left);
if(pRoot->right != NULL)
Mirror(pRoot->right);
}
};

## 面试题23：从上到下打印二叉树

class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root) {
vector<int> result;
if(root == NULL)
return result;
queue<TreeNode*> treeQueue;
treeQueue.push(root);
while(!treeQueue.empty()){
TreeNode *tmp = treeQueue.front();
treeQueue.pop();
result.push_back(tmp->val);
if(tmp->left != NULL)
treeQueue.push(tmp->left);
if(tmp->right != NULL)
treeQueue.push(tmp->right);
}
return result;
}
};

## 面试题24：二叉搜索树的后序遍历序列

class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
return PostBST(sequence,0,sequence.size()-1);
}
bool PostBST(vector<int> sequence, int start, int end){
if(end < start)
return false;
//int len = end - start + 1;
int root = sequence[end]; //找到根结点
int i = start;
//在二叉搜索树中左子树的结点小于根结点
for(;i<end;i++){
if(sequence[i] > root)
break;
}
int j = i;
//在二叉搜索树中右子树的结点大于根结点
for(;j<end;j++){
if(sequence[j] < root)
return false;
}
//判断左子树是不是二叉搜索树
bool left = true;
if(i>start)
left = PostBST(sequence,start,i-1);
//判断右子树是不是二叉搜索树
bool right = true;
if(i<end-1)
right = PostBST(sequence,i,end-1);
return (left && right);
}
};

## 面试题25：二叉树中和为某一值的树

class Solution {
public:
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root != NULL){
int currentSum = 0;
vector<int> path;
find(root, expectNumber, currentSum, path);
}
return result;
}
void find(TreeNode* root,int expectNumber,int currentSum,vector<int>& path){
currentSum += root->val;
path.push_back(root->val);
bool isLeaf = (root->left == NULL && root->right == NULL);
if(isLeaf && currentSum == expectNumber){
result.push_back(path);
}
if(root->left != NULL)
find(root->left, expectNumber, currentSum, path);
if(root->right != NULL)
find(root->right, expectNumber, currentSum, path);
path.pop_back();
}
private:
vector<vector<int>> result;
};

## 面试题39：二叉树的深度

class Solution {
public:
int TreeDepth(TreeNode* pRoot)
{
if(pRoot == NULL)
return 0;
return getDepth(pRoot);
}
int getDepth(TreeNode* pRoot){
int leftDepth = 0, rightDepth = 0;
if(pRoot->left != NULL)
leftDepth = getDepth(pRoot->left);
if(pRoot->right != NULL)
rightDepth = getDepth(pRoot->right);
return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
}
};

class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot == NULL)
return true;
int pDepth;
return IsBalanced(pRoot,pDepth);
}
bool IsBalanced(TreeNode* pRoot, int &pDepth){  //pDepth不要忘记加&
if(pRoot == NULL){
pDepth = 0;
return true;
}
int left,right;
if(IsBalanced(pRoot->left,left) && IsBalanced(pRoot->right,right)){  //后序遍历的体现
if((left-right)>=-1 && (left-right)<=1){
pDepth = 1+(left>right?left:right);
return true;
}
}
return false;
}
};

## 面试题58：二叉树的下一个结点

class Solution {
public:
{
if(pNode == NULL)
return NULL;
if(pNode->right != NULL){
while(pRight->left != NULL)
pRight = pRight->left;
pNext = pRight;
}else if(pNode->next != NULL){ //此处next是指向父结点的指针
while(pParent!=NULL && pCurrent == pParent->right){
pCurrent = pParent;
pParent = pCurrent->next;
}
pNext = pParent;
}
return pNext;
}
};

## 面试题59：对称的二叉树

class Solution {
public:
bool isSymmetrical(TreeNode* pRoot)
{
return isSymmetrical(pRoot,pRoot);
}
bool isSymmetrical(TreeNode* pRoot1,TreeNode* pRoot2){
if(pRoot1 == NULL && pRoot2 == NULL)
return true;
if(pRoot1 == NULL || pRoot2 == NULL)
return false;
if(pRoot1->val != pRoot2->val)
return false;
return isSymmetrical(pRoot1->left,pRoot2->right) && isSymmetrical(pRoot1->right,pRoot2->left);
}
};

## 面试题60：把二叉树打印成多行

class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int>> result;
if(pRoot == NULL)
return result;
queue<TreeNode*> tree;
tree.push(pRoot);
int curLayerCnt = 1;
int nextLayerCnt = 0;
vector<int> helpVec;//辅助vector，保存每一层的结点值
while(!tree.empty()){
TreeNode* tmp = tree.front();
helpVec.push_back(tmp->val);
tree.pop();
if(tmp->left != NULL){
tree.push(tmp->left);
nextLayerCnt++;
}
if(tmp->right != NULL){
tree.push(tmp->right);
nextLayerCnt++;
}
curLayerCnt--;
if(curLayerCnt == 0){
result.push_back(helpVec);
helpVec.clear();
curLayerCnt = nextLayerCnt;
nextLayerCnt = 0;
}
}
return result;
}
};

## 面试题61：按之字形顺序打印二叉树

class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int>> result;
if(pRoot == NULL)
return result;
stack<TreeNode*> levels[2]; //定义了两个栈
int current = 0;
int next = 1;
levels[current].push(pRoot);
vector<int> helpVec; //辅助vector
while(!levels[current].empty()){
TreeNode* tmp = levels[current].top();
levels[current].pop();
helpVec.push_back(tmp->val);
if(current == 0){  //当前层是奇数层
if(tmp->left!=NULL)
levels[next].push(tmp->left);
if(tmp->right!=NULL)
levels[next].push(tmp->right);
}
else{  //当前层是偶数层
if(tmp->right!=NULL)
levels[next].push(tmp->right);
if(tmp->left!=NULL)
levels[next].push(tmp->left);
}
if(levels[current].empty()){
result.push_back(helpVec);
helpVec.clear();
current = 1 - current;
next = 1 - next;
}
}

return result;
}
};

## 面试题62：系列化二叉树

class Solution {
public:
char* Serialize(TreeNode *root) {
if(!root)
return "#";
string r = to_string(root->val);
r.push_back(',');
char* left = Serialize(root->left);
char* right = Serialize(root->right);
char* ret = new char[strlen(left) + strlen(right) + r.length()];
strcpy(ret,r.c_str());
strcat(ret,left);
strcat(ret,right);
return ret;
}
TreeNode* Decode(char *&str) {
if(*str == '#'){
str++;
return NULL;
}
int num = 0;
while(*str!=','){
num = num*10+(*(str++))-'0';
}
str++;
TreeNode* root = new TreeNode(num);
root->left = Decode(str);
root->right = Decode(str);
return root;
}
TreeNode* Deserialize(char *str) {
return Decode(str);
}
};

## 面试题63：二叉搜索树的第k个结点

class Solution {
public:
TreeNode* KthNode(TreeNode* pRoot, int k)
{
if(pRoot == NULL || k == 0)
return NULL;
return KthNodeCore(pRoot,k);
}

TreeNode* KthNodeCore(TreeNode* pRoot,int &k){
TreeNode* target = NULL;
if(pRoot->left != NULL)
target = KthNodeCore(pRoot->left,k);
if(target == NULL){
if(k == 1)
target = pRoot;
else
k--;
}
if(target == NULL && pRoot->right != NULL)
target = KthNodeCore(pRoot->right,k);
return target;
}
};