1.判断两颗二叉树是否相同(左右子树不能旋转):可以采用递归方法实现
struct binaryNode {
int m_ivalue;
binaryNode* m_pLeft;
binaryNode* m_pRight;
};
bool _isEqual(binaryNode* node1, binaryNode*node2)
{
if (node1 == NULL&&node2 == NULL)
return 1;
if (!node1 || !node2)
return 0;
if (node1->m_ivalue == node2->m_ivalue)
return _isEqual(node1->m_pLeft, node2->m_pLeft) && _isEqual(node1->m_pRight, node2->m_pRight);
else
return 0;
}
如果左右子树可以旋转,只需要修改以上返回递归条件部分:
return (_isEqual(node1->m_pLeft, node2->m_pLeft) && _isEqual(node1->m_pRight, node2->m_pRight))|| (_isEqual(node1->m_pLeft, node2->m_pRight) && _isEqual(node1->m_pRight, node2->m_pLeft));
2.求二叉树的深度
输入一棵二叉树的根节点,求该树的深度。从根节点到叶子结点以此经过的结点形成树的一条路径,最长路径的长度为树的深度。本质还是二叉树遍历,需要求出左右子树的深度,才能求出根节点的深度,使用后序遍历。
truct SBinaryTreeNode {
int m_nValue;
SBinaryTreeNode* m_pLeft;
SBinaryTreeNode* m_pRight;
};
int tree_height(SBinaryTreeNode* root)
{
int left, right;
if (root == NULL)
return -1;
else
{
left = tree_height(root->m_pLeft) + 1;
right = tree_height(root->m_pRight)+1;
return (left > right) ? left : right;
}
}
3.求二叉树中结点的最大距离
定义:父子结点之间的连线是双向的,距离为两结点之间边的个数,求一棵二叉树中距离最远的两个结点之间的距离。
这个问题的核心是,情况A和B需要不同的信息:A需要子树的最大深度,B需要子树的最远距离。只要函数能在一个结点同时计算及传回这两个信息。
struct node
{
int value;
struct node* pLeft;
struct node* pRight;
};
struct result
{
int nMaxdistance;
int nMaxdepth;
};
result GetMaximumDistance(node* root)
{
if (!root)
{
result empty = {0,-1};
return empty;
}
result lhs = GetMaximumDistance(root->pLeft);
result rhs = GetMaximumDistance(root->pRight);
result res;
res.nMaxdepth = max(lhs.nMaxdepth+1,rhs.nMaxdepth+1);
res.nMaxdistance = max(max(lhs.nMaxdistance,rhs.nMaxdistance),lhs.nMaxdepth+rhs.nMaxdepth+2);
return res;
}
nMaxDepth就是左子树和右子树的深度加1.nMaxDistance取A和B情况的最大值。
4.一棵二叉树每个结点包含一个整数,求此路径上所有结点之和为给定值(不必须从根节点开始)
案例:5,则2+3-4+3+1+2这条路径包含多个满足条件的子路径。(先序遍历)
struct TreeNode
{
int data;
struct TreeNode* left;
struct TreeNode* right;
};
void printbuffer(vector<int> buffer,int level,int i2)
{
for (int i = level; i <= i2; i++)
cout << buffer[i] << " ";
cout << endl;
}
void findSum(TreeNode* head, int sum, vector<int>buffer, int level)
{
if (head == NULL)
return;
int tmp = sum;
buffer.push_back(head->data);
for (int i = level; i > -1; i--)
{
tmp -= buffer[i];
if (tmp == 0)
printbuffer(buffer,i,level);
}
findSum(head->left,sum,buffer,level+1);
buffer.pop_back();
level -= -1;
findSum(head->right,sum,buffer,level+1);
}
5.由遍历序列构造二叉树
由二叉树的先序遍历和中序遍历可以确定一棵二叉树。由二叉树的中序遍历和后序遍历可以确定一棵二叉树。(由二叉树的先序遍历和后序遍历是无法唯一确定一棵二叉树)
6.输入某二叉树的前序遍历和中序遍历的结果,请重新建出该二叉树。假设输入的前序遍历和中序遍历的结果都不含重复数字。前序遍历{1,2,4,7,3,5,6,8}中序遍历{4,7,2,1,5,3,8,6},重建二叉树并输出他的后序遍历。
思路:在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中.根结点的值在序列的中间.左子树的结点的值位于根结点的值的左边,而右子树的结点点的值位于根结点的值的右边·因此我们通过扫描中序遍历序列.可以找到根结点的值.然后可以得出其左子树结点集与右子树结点集,也即得到了其左、右子树的前序遍历序列和中序遍历序列。我们可以用同样的方法分别去构建左右子树,本题可以用递归的方法来完成。
struct BinaryTreeNode {
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
BinaryTreeNode* Construct(int *preorder, int*inorder, int length)
{
if (preorder == NULL || inorder == NULL || length <= 0)
return NULL;
return ConstructCore(preorder, preorder + length - 1, inorder, inorder + length - 1);
}
BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int * startInorder, int *endInorder)
{
//前序遍历序列的第一个数字是根节点的值
int rootValue = startPreorder[0];
BinaryTreeNode* root = new BinaryTreeNode(); //建立结点
root->m_nValue = rootValue;
root->m_pLeft = root->m_pRight = NULL;
if (startPreorder == endPreorder) //边界条件
{
if (startInorder == endInorder&&*startPreorder == *endPreorder)
return root;
else
throw std::exception("invalid input.");
}
//在中序遍历中找到根节点的值
int *rootInorder = startInorder;
while (rootInorder <= endInorder&&*rootInorder != rootValue)
++rootInorder;
if (rootInorder == endInorder&&*rootInorder != rootValue)
throw std::exception("invalid input.");
int leftLength = rootInorder - startInorder;
int *leftPreorderEnd = startPreorder + leftLength;
if (leftLength > 0)
{//构建左子树
root->m_pLeft = ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
}
if (leftLength < endPreorder - startPreorder)
{//构建右子树
root->m_pRight = ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
}
return root;
}