二叉树的遍历(递归与迭代)

来源:互联网 发布:java权限管理设计rbac 编辑:程序博客网 时间:2024/04/27 22:46

1、前序遍历

访问顺序:根->左子树->右子树

递归实现:


/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * };**/  vector<int> preorderTraversal(TreeNode *root) {        vector<int> v;        vector<int> temp1;        vector<int> temp2;        vector<int>::iterator it;        if(root!=NULL)        {            v.push_back(root->val);            temp1=preorderTraversal(root->left);            it=temp1.begin();            while(it!=temp1.end())           {                v.push_back((*it));                it++;           }                            temp2=preorderTraversal(root->right);            it=temp2.begin();            while(it!=temp2.end())           {                v.push_back((*it));                it++;           }        }                return v;    }


迭代实现:

利用栈作为辅助空间,回溯访问二叉树的节点

vector<int> preorderTraversal(TreeNode *root) {        vector<int> v;        stack<TreeNode *> s;        TreeNode *p=root;        while(p!=NULL||!s.empty())        {            if(p!=NULL)            {                v.push_back(p->val);//visit(p->val);                s.push(p);                p=p->left;            }            else            {                p=s.top()->right;                s.pop();            }                                }        return v;    }

2、中序遍历

访问顺序:  左子树->根节点->右子树

递归实现:

vector<int> inorderTraversal(TreeNode *root) {       vector<int> v;       vector<int>::iterator it;       vector<int> temp1;       vector<int> temp2;       if(root!=NULL)       {           temp1=inorderTraversal(root->left);           it=temp1.begin();           while(it!=temp1.end())           {               v.push_back((*it));               it++;           }                                 v.push_back(root->val);                                            temp2=inorderTraversal(root->right);           it=temp2.begin();           while(it!=temp2.end())           {               v.push_back((*it));               it++;           }       }              return v;    }


可以看出中序遍历和前序遍历十分相像。


迭代实现:

vector<int> inorderTraversal(TreeNode *root) {       vector<int> v;        stack<TreeNode *> s;        TreeNode *p=root;        while(p!=NULL||!s.empty())        {            if(p!=NULL)            {               // v.push_back(p->val);                s.push(p);                p=p->left;            }            else            {                v.push_back((s.top())->val);                p=s.top()->right;                s.pop();            }                                }        return v;    }

3、后序遍历

访问顺序:左子树->右子树->根


递归实现:

  vector<int> postorderTraversal(TreeNode *root) {        vector<int> v;        vector<int>::iterator it;        vector<int> temp1;        vector<int> temp2;        //TreeNode *p=root;        if(root!=NULL)        {            temp1=postorderTraversal(root->left);            it=temp1.begin();            while(it!=temp1.end())            {                v.push_back((*it));                it++;            }                                                temp2=postorderTraversal(root->right);            it=temp2.begin();            while(it!=temp2.end())            {                v.push_back((*it));                it++;            }                                    v.push_back(root->val);        }                return v;    }


迭代实现:

参考:http://oj.leetcode.com/discuss/1514/accepted-but-my-solution-destroys-the-original-tree


vector<int> postorderTraversal(TreeNode *root) {        vector<int> v;        stack<TreeNode *> s;        TreeNode *last=root;        if(root==NULL)            return v;                   s.push(root);        while(!s.empty())        {            TreeNode * cur=s.top();            //如果是叶子节点:cur->left==NULL&&cur->right==NULL,则打印            //如果cur节点的左右子树都被访问了:cur->right==last,则打印            //如果cur节点的左子树被访问了,而右子树为空:cur->left==last&&cur->right==NULL,则打印            if((cur->left==NULL&&cur->right==NULL)||cur->right==last||(cur->left==last&&cur->right==NULL))            {                v.push_back(cur->val);                last=cur;                s.pop();            }            else            {                if(cur->right!=NULL)//右子树先入栈,后访问                    s.push(cur->right);                if(cur->left!=NULL)//左子树后入栈,先访问                    s.push(cur->left);            }        }        return v;    }



0 0