leetcode105 && leetcode106 && PAT 1138. 二叉树的三种遍历的应用

来源:互联网 发布:那个软件看电影免费 编辑:程序博客网 时间:2024/06/11 04:56

俗话说的好“你先前跳过的坑,迟早都要再踩进去的”
昨天考的PAT的利用二叉树的前序和中序遍历得到后序遍历的第一个值。想起在leetcode上做过,却没做出来。特此,对二叉树的三种遍历做个复习。

二叉树的三种遍历分别为:前序遍历(preorder),中序遍历(inorder),后序遍历(postorder),这三种遍历的区别直接体现在代码上,看如下三个代码:

void preorder(TreeNode* root){    printNode(root);    preorder(root->left);    preorder(root->right);}
void inorder(TreeNode* root){    inorder(root->left);    printNode(root);    inorder(root->right);}
void postorder(TreeNode* root){    postorder(root->left);    postorder(root->right);    printNode(root);}

以上就是三种遍历方式的代码,代码就是纯递归。只是输出的不同。那么,再来看下面的实例:
这里写图片描述

那么前序遍历(preorder)为:ABDCEGFHI
中序遍历(inorder)为:BDAGECHFI
后序遍历(postorder)为:DBGEHIFCA
大家可以根据上面的代码,自己推断一下遍历的结果。
从这些遍历的结果可以看到以下几个特点:
1.遍历的优先级左边优先.
2.前序遍历不断递归左边的点(将遇到的点入栈).
3.递归到底了,返回上面一层到右边(出栈),发生转变的时候,前序遍历的值会刚好等于中序遍历的值.
4.后序遍历刚刚看起来好像没什么规律。但是将后序遍历反转一下呢?得到如下的结果:ACFIHEGBD。再观察一下树,没错了,反转之后得到的结果是树的优先向右遍历的结果。但是什么时候判断到底,也就是什么时候判断要转向了呢?我们也照反转的方式,将中序遍历反转,得到结果:IFHCEGADB。哈哈,没错这是当反转的后序等于反转的中序的时候就说明到底了,需要转向了。

知道了上面四点性质,下面这三道题就很简单了:
leetcode105:
利用前序遍历和后序遍历构建树。
根据性质1,2,3
建立一个栈,遍历前序向栈压结点。直到和中序遍历的值相等,说明到底,出栈,转向。
代码如下:

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {        if(preorder.empty() || inorder.empty()) return NULL;        stack<TreeNode*> stree;        int size=inorder.size();        int i=1;        int j=0;        int flag=0;     //向右进行的标志        TreeNode* node=new TreeNode(preorder[0]);        TreeNode* root=node;        if(preorder.size()==1) return root;        stree.push(node);        while(i<size)        {            //表示应该转向了            if(!stree.empty() && ((stree.top())->val==inorder[j]))            {                node=stree.top();                stree.pop();                flag=1;                j++;            }            else            {                TreeNode* tmp=new TreeNode(preorder[i]);                i++;                if(flag==0)                {                    node->left=tmp;                    node=node->left;                    stree.push(tmp);                }                else                {                    node->right=tmp;                    node=node->right;                    stree.push(tmp);                    flag=0;                }            }        }        return root;    }};

106.利用后序遍历和中序遍历还原树
根据性质四.将中序遍历和后序遍历的结果反转,将右的优先级调整高于左,和上面一样的思路。
代码如下:

/** * Definition for a binary tree node. * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {    if(inorder.empty()) return NULL;    stack<TreeNode *>st;    reverse(inorder.begin(),inorder.end());    reverse(postorder.begin(),postorder.end());    TreeNode* root=new TreeNode(postorder[0]);    TreeNode* node=root;    st.push(node);    int i=1; int j=0; int flag=0;   //0说明向右    int size=postorder.size();    while(i<size)    {        if(!st.empty() && (st.top()->val)==inorder[j])        {            node=st.top();            st.pop();            j++;            flag=1;      //1说明转向,转向到左        }        else        {            TreeNode *temp=new TreeNode(postorder[i]);            if(flag==0)            {                node->right=temp;                node=node->right;            }            else            {                flag=0;                node->left=temp;                node=node->left;            }            st.push(temp);            i++;        }    }    return root;    }};

PAT 1138.给出前序和中序遍历,给出后序的第一个值。这个,不多说了
代码:

#include<cstdio>#include<string>#include<stack>#include<iostream>using namespace std;struct TreeNode{    int value;    TreeNode* left;    TreeNode* right;    TreeNode(int x):value(x),left(NULL),right(NULL) {}};int a[50001];int b[50001];int flag3=0;void postorder(TreeNode* a);int main(){    int n;    cin>>n;    for(int i=0;i<n;++i)    {        cin>>a[i];    }        for(int i=0;i<n;++i)    {        cin>>b[i];    }    if(n==1)    {        cout<<a[0];    }    int flag=0;    int i=1;    int j=0;    stack<TreeNode *>st;    TreeNode* root=new TreeNode(a[0]);    TreeNode* node=root;    st.push(root);    while(i<n)    {        //转向        if(!st.empty() && (st.top())->value==b[j])        {            node=st.top();            st.pop();            flag=1;            j++;        }        else        {            TreeNode* tmp=new TreeNode(a[i]);            i++;            if(flag==0)            {                node->left=tmp;                node=node->left;                st.push(node);            }            else            {                node->right=tmp;                node=node->right;                st.push(node);                flag=0;            }        }    }    postorder(root);}void postorder(TreeNode* a){    if(flag3==1 || a==NULL)    {        return;    }    else    {        postorder(a->left);        postorder(a->right);        if(flag3==0)        {            cout<<(a->value);            flag3=1;        }    }}
原创粉丝点击