剑指offer6:重建二叉树
描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
例如二叉树的结构如下图所示
#include "stdafx.h"
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
BinaryTreeNode(int x) :m_nValue(x), m_pLeft(NULL), m_pRight(NULL) {}
};
BinaryTreeNode * ConstructCore(vector<int> pre, vector<int> vin)
{
if (pre.empty() || vin.empty() || pre.size() != vin.size())
return NULL;
int index = 0;//保存中序遍历中根结点的位置参数
vector<int> left_pre, left_vin, right_pre, right_vin;
BinaryTreeNode* root = new BinaryTreeNode(pre[0]);
//如果只有一个结点则直接返回
if (pre.size() == 1)
{
if (vin.size() == 1 && pre[0] == vin[0])
return root;
else
{
cout << "Invalid input." << endl;
return nullptr;
}
}
//在中序遍历序列中找到根结点
for (int i = 0; i < vin.size(); i++)
{
if (vin[i] == pre[0])
{
index = i;
break;
}
}
//分左右子树,见图分析
for (int i = 0; i<index; i++)
{
//cout <<" m "<< endl;
left_pre.push_back(pre[i + 1]);
left_vin.push_back(vin[i]);
}
for (int i = index + 1; i<vin.size(); i++)
{
right_pre.push_back(pre[i]);
right_vin.push_back(vin[i]);
}
//递归
root->m_pLeft = ConstructCore(left_pre, left_vin);
root->m_pRight = ConstructCore(right_pre, right_vin);
return root;
}
//二叉树前序遍历打印
void PreOrderPrint(BinaryTreeNode* pHead)
{
if (pHead == NULL)
return;
cout << pHead->m_nValue << "->";
PreOrderPrint(pHead->m_pLeft);
PreOrderPrint(pHead->m_pRight);
}
//二叉树的中序遍历打印
void InOrderPrint(BinaryTreeNode* pHead)
{
if (pHead == NULL)
return;
InOrderPrint(pHead->m_pLeft);
cout << pHead->m_nValue << "->";
InOrderPrint(pHead->m_pRight);
}
//二叉树的后序遍历打印
void PostOrderPrint(BinaryTreeNode* pHead)
{
if (pHead == NULL)
return;
PostOrderPrint(pHead->m_pLeft);
PostOrderPrint(pHead->m_pRight);
cout << pHead->m_nValue << "->";
}
int main()
{
vector<int> Vinn{ 4,7,2,1,5,3,8,6 };
vector<int> Pree{ 1,2,4,7,3,5,6,8 };
//vector<int> Vinn{ 1 };//测试用例
//vector<int> Pree{2};//测试用例
BinaryTreeNode* newRoot = ConstructCore(Pree, Vinn);
cout << "先序遍历:" << endl;
PreOrderPrint(newRoot);
cout<<endl << "中序遍历:" << endl;
InOrderPrint(newRoot);
cout<<endl << "后序遍历:" << endl;
PostOrderPrint(newRoot);
cout << endl;
return 0;
}
测试结果:
剑指offer18:树的子结构
题目描述:输入两颗二叉树A和B,判断B是不是A的子结构。
解题技巧:
第一步,在树A中找到和B根结点值一样的结点R;
第二步,判断树A中以R为根结点的子树是不是包含和树B一样的结构
bool HasSubTree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
if (pRoot1 == pRoot2)
return true;
if (pRoot2 == NULL)
return true;
if (pRoot1 == NULL)
return false;
if (pRoot1->m_nValue = pRoot2->m_nValue)
{
bool Lflag = HasSubTree(pRoot1->m_pLeft, pRoot2->m_pLeft);
bool Rflag = HasSubTree(pRoot1->m_pRight, pRoot2->m_pRight);
if (Lflag&&Rflag)
return true;
}
bool Lflag = HasSubTree(pRoot1->m_pLeft, pRoot2);
bool Rflag = HasSubTree(pRoot1->m_pRight, pRoot2);
if (Lflag || Rflag)
{
return true;
}
else
return false;
}