Binary tree traversal_pre-order middle-order determine its subsequent order (C++)

Foreword:

  Speaking of binary trees, I wrote a blog before about the traversal of binary trees, but why do you repeat it?

  Of course, because of the difference. This also solves one of my previous doubts about trees. When I built the tree at that time, it was a pre-order tree. Only the result of pre-order traversal cannot uniquely determine a binary tree. Therefore, I used a form similar to ab null null c null null to determine the shape of the tree. After the middle order traversal and any one of (pre-order traversal and post-order traversal), the binary tree shape can be determined, so just write the sequence instead of null.

problem:

  Know the pre-order traversal and middle-order traversal of a binary tree to find the subsequent traversal.

  enter:

  ABC
  BAC


  FDXEAG
  XDEFAG

principle:

  First of all, the first element of the pre-order traversal (left and right) must be the root node, then by looking for the position of the root node in the middle-order traversal (left root right), you can

The middle-order sequence is divided into left and right subtrees. Assuming its length is l and r, the sequence length of its preorder traversal can be expressed as: 1+l+r, which represent the root, left subtree, and right subtree respectively.

In the same way, the same operation is performed on the left and right subtrees respectively to determine the shape of the binary tree.

Of course, post-order traversal and mid-order traversal are also applicable.

Ok,let‘s see the code now !

 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>


//二叉树遍历。
//前序+中序确定一棵树。
//同理:后序+中序确定一棵树。
/*
思想:
前序和后序能确定根节点的位置,
通过查找中序遍历根节点的位置,可以确定其左右子树,
对其左右子树进行同样的操作,递归即得二叉树的形态。
*/


using namespace std;

string sPre,sIn;//前序遍历和中序遍历的字符串。


struct node{
    char weight;
    node* lChild;
    node* rChild;
};

node* buildTree(int s1,int e1,int s2,int e2)
{
    node* root=new node({sPre[s1],NULL,NULL});
    int rootId;
    for(int i=s2;i<=e2;i++)//寻找中序遍历root结点的位置
    {
        if(sIn[i]==sPre[s1])
            {
                rootId=i;
                break;
            }
    }

    if(rootId!=s2)//如果中序遍历的根节点前面有结点肯定是其左子树,其结点个数为rootId-s2
    {
        root->lChild=buildTree(s1+1,s1+rootId-s2,s2,rootId-1);
    }
    if(rootId!=e2)//同理,中序遍历根节点后面有结点肯定是其右子树,结点数为e2-rootId
    {
        root->rChild=buildTree(e1-e2+rootId+1,e1,rootId+1,e2);
    }
    return root;

}



void postOrder(node* root)
{
    if(root->lChild!=NULL)
        postOrder(root->lChild);
    if(root->rChild!=NULL)
        postOrder(root->rChild);
    cout<<root->weight;
}



int main()
{

    while(cin>>sPre>>sIn)
    {

        node*root=buildTree(0,sPre.length()-1,0,sIn.length()-1);
        postOrder(root);
        cout<<endl<<endl;
    }


    return 0;
}

result:

to sum up:

The problem itself is not difficult, but it solves one of my own questions, it is worth it!

Guess you like

Origin blog.csdn.net/Look_star/article/details/99201701