最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
C++中前序遍历和中序遍历重建二叉树例子
时间:2022-06-25 08:07:40 编辑:袖梨 来源:一聚教程网
已知某二叉树的前序遍历结果和中序遍历结果,假如前序遍历和中序遍历的结果中都不含重复的数字。例如某个二叉树的前序遍历的序列为{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;
}
先把三种遍历算法写上:
// 前序遍历
void preOrder(BinaryTreeNode* binaryTreeNode){
if (binaryTreeNode != NULL)
{
printf("%d ",m_pLeft->m_nValue);
preOrder(binaryTreeNode->m_pLeft);
preOrder(binaryTreeNode->m_pRight);
}
}
// 中序遍历
void inOrder(BinaryTreeNode* binaryTreeNode){
if (binaryTreeNode != NULL)
{
inOrder(binaryTreeNode->m_pLeft);
printf("%d ",binaryTreeNode->m_nValue);
inOrder(binaryTreeNode->m_pRight);
}
}
// 后续遍历
void postOrder(BinaryTreeNode* binaryTreeNode){
if(binaryTreeNode != NULL)
{
postOrder(binaryTreeNode->m_pLeft);
postOrder(binaryTreeNode->m_pRight);
printf("%d ",m_pLeft->m_nValue);
}
}
主要还是利用递归,因为二叉树本身就是一种递归的产物,而且又是有序的,所以找到规律递推处理即可。根据上面的图应该可以分析出下面的代码:
BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder){
// 前序遍历序列的第一个数字是根节点
int rootValue = startInorder[0];
BinaryTreeNode* root = new BinaryTreeNode();
root->m_nValue = rootValue;
root->m_pLeft = root->m_pRight = NULL;
// 在中序遍历中找到根节点
int* rootInorder = startInorder;
// 如果当前指针对应的指不是根节点,那么指针向后移动一次
while(rootInorder <= endInorder && *rootInorder != rootValue){
++ rootInorder;
}
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;
}
加以完善,考虑周全些:
BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int* endInorder){
// 前序遍历序列的第一个数字是根节点
int rootValue = startInorder[0];
BinaryTreeNode* root = new BinaryTreeNode();
root->m_nValue = rootValue;
root->m_pLeft = root->m_pRight = NULL;
if (startPreorder == endPreorder)
{
if (startInorder == endInorder && *startPreorder == *startInorder)
{
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;
}
相关文章
- 人们熟悉的寄居蟹属于以下哪种分类 神奇海洋11月21日答案 11-21
- 第五人格11.22共研服有什么更新 11月22日共研服更新内容介绍 11-21
- 原神恰斯卡怎么培养 11-21
- 无期迷途四星装束是谁 11-21
- 王者荣耀帝丹高中校服怎么获得 11-21
- 光遇姆明季后续版本怎么玩 11-21