先序遍历中序遍历后序遍历确定一棵二叉树(递归、非递归)

来源:互联网 发布:图片文字编辑器软件 编辑:程序博客网 时间:2024/05/21 10:54

先序遍历&中序遍历

递归做法:
递归做法比较容易理解,先在先序遍历中确定第一个点,这个点一定是根节点,然后在中序遍历中找到这个点的位置,那么这个位置之前的都是左子树,后边的都是右子树,然后分别递归。

class Solution {public:    int start = 0;    TreeNode* build(vector<int>& pre,vector<int>& in, int ps,int pe, int is, int ie){        if (ps>=pe)            return NULL;        int val = pre[ps];        TreeNode* root = new TreeNode(val);        int pos;        for (int i=is;i<ie;i++){            if (in[i]==val) {                pos=i;                break;            }        }        root->left = build(pre,in,ps+1,ps+pos-is+1,is,pos);        root->right= build(pre,in,pe-ie+pos+1,pe,pos+1,ie);        return root;    }    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {        return build(preorder,inorder,0,preorder.size(),0,inorder.size());    }};

非递归:
非递归的做法有些不好理解,核心思想有两点:
1 从先序遍历序列的头部开始从左向右访问,用一个栈保存访问过的节点,每次都要判断栈顶元素是否等于中序遍历的当前节点。

2 如果相等,说明栈顶节点左子树遍历完毕,那么接下来的节点应该是前驱节点的右节点,标志位置1。如果不相等,那么先序遍历的下一个节点依然是前驱节点的左节点或右节点,需要根据标志位确定。

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {        stack<TreeNode*> st;        int n = int(preorder.size());        if (n == 0) return NULL;        int i = 1, j = 0;        TreeNode* root = new TreeNode(preorder[0]);        bool flag = 0;        TreeNode* pre = root;        st.push(root);        while (i < n){            if (!st.empty() && st.top() -> val == inorder[j]){                pre = st.top();                st.pop();                flag = 1;                j++;            }            else if (flag){                pre -> right = new TreeNode(preorder[i++]);                pre = pre -> right;                st.push(pre);                flag = 0;            }            else{                pre -> left = new TreeNode(preorder[i++]);                pre = pre -> left;                st.push(pre);            }        }        return root;    }

中序遍历&后序遍历
基本类似,区别是从后向前遍历后序序列
递归:

class Solution {public:    int find(vector<int> inorder, int v){        for (int i = 0; i < inorder.size(); ++i){            if (inorder[i] == v) return i;        }        return -1;    }    TreeNode* build(vector<int>& inorder, vector<int>& postorder, int s1, int e1, int s2, int e2){        if (s1 > e1) return NULL;        else{            int v = postorder[e2];            int index = find(inorder, v);            TreeNode* root = new TreeNode(v);            root -> left = build(inorder,postorder,s1,index-1,s2,s2+index-1-s1);            root -> right = build(inorder,postorder,index+1,e1,s2+index-s1,e2-1);            return root;        }    }    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {        int n = inorder.size();        if (n == 0) return NULL;        return build(inorder,postorder,0,n-1,0,n-1);    }};

非递归

TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {        int n = inorder.size();        if (n == 0) return NULL;        int i = n-1, j = n-2;        TreeNode* root = new TreeNode(postorder[n-1]);        TreeNode* pre = root;        stack<TreeNode*> st;        st.push(root);        bool flag = 0;        while (i >= 0){            if (!st.empty() && st.top() -> val == inorder[i]){                pre = st.top();                st.pop();                i--;                flag = true;            }else if (flag){                pre -> left = new TreeNode(postorder[j--]);                pre = pre -> left;                st.push(pre);                flag = 0;            }else{                pre -> right = new TreeNode(postorder[j--]);                pre = pre -> right;                st.push(pre);            }        }        return root;    }
0 0
原创粉丝点击