二叉树非递归遍历--迭代

来源:互联网 发布:mysql 入侵 编辑:程序博客网 时间:2024/04/27 23:56

无论是何种遍历都抓住遍历的特征


先、中、后,三种遍历方式,都是深度优先搜索,差别仅在于访问根节点的顺序。

深度优先搜索的特点:

1、使用栈。

2、存在可访问节点时,向下延伸。

3、无可访问节点时,回退至上级可访问节点。


二叉树先、中、后遍历中DFS思想的体现:

1、使用栈。

2、左子树存在,向左子树迭代。

3、左子树不存在,移向右子树,回2。


1、先序

特征:一直向左,对访问的节点进行入栈,直到左边没有,回退,向右一步,再回到一直向左。

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> preorderTraversal(TreeNode *root) {        stack<TreeNode *> pStack;        while (root || !pStack.empty()) {            while (root) {                result.push_back(root->val);                pStack.push(root);                root = root->left;            }                        if (!pStack.empty()) { // 这里栈不会为空,所以可以去掉                root = pStack.top();                pStack.pop();                root = root->right;            }        }        return result;    }private:    vector<int> result;};



2、中序

特征:一直向左,不访问,入栈,回退访问,向右,再一直向左

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> inorderTraversal(TreeNode *root) {        stack<TreeNode *> pStack;        while (root || !pStack.empty()) {            while (root) {                pStack.push(root);                root = root->left;            }                        if (!pStack.empty()) {                root = pStack.top();                pStack.pop();                result.push_back(root->val);                root = root->right;            }        }        return result;    }private:    vector<int> result;};



3、后序

特征:叶节点直接访问;非叶节点,子树必须已访问,上一个被访问的必然是子节点

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> postorderTraversal(TreeNode *root) {        if (root == NULL) {            return result;        }        stack<TreeNode *> s;        TreeNode *pre = NULL;        s.push(root);        while (!s.empty()) {            root = s.top();            if (root->left == NULL && root->right == NULL) {                result.push_back(root->val);                pre = root;                s.pop();            } else if (root->right != NULL && pre == root->right) {                result.push_back(root->val);                pre = root;                s.pop();            } else if (root->left != NULL && pre == root->left) {                result.push_back(root->val);                pre = root;                s.pop();            } else {                if (root->right && pre != root->right) {                    s.push(root->right);                }                if (root->left && pre != root->left) {                    s.push(root->left);                }            }        }        return result;    }    private:    vector<int> result;};


考虑到节点如果有左子树,则必然先背访问,那么需要考虑的是右子树如果存在,有没有被访问呢?

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> postorderTraversal(TreeNode *root) {        if (root == NULL) {            return result;        }        stack<TreeNode *> s;        TreeNode *pre = NULL;        TreeNode *cur = root;        while (cur || !s.empty()) {            while (cur) {                s.push(cur);                cur = cur->left;            } // 一直向左子树方向探索            cur = s.top();            if (cur->right == NULL || pre == cur->right) {                result.push_back(cur->val);                pre = cur;                s.pop();                cur = NULL;            } else {                cur = cur->right;            }        }        return result;    }    private:    vector<int> result;};


优化


迭代条件是
1、节点不空,此时栈可能为空,进入迭代会将节点入栈;
2、或者栈不空
因此在任何遍历出栈的时候,都可以保证栈是不空的,在出栈前也就没有必要判断栈是否为空。

优化的先序

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> preorderTraversal(TreeNode *root) {        stack<TreeNode *> s;        TreeNode *cur = root;        while (cur || !s.empty()) {            while (cur) {                re.push_back(cur->val);                s.push(cur);                cur = cur->left;            }            cur = s.top();            cur = cur->right;            s.pop();        }        return re;    }private:    vector<int> re;};


优化的中序

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> inorderTraversal(TreeNode *root) {        stack<TreeNode *> s;        while (root || !s.empty()) {            while (root) {                s.push(root);                root = root->left;            }                        root = s.top();            s.pop();            re.push_back(root->val);            root = root->right;        }        return re;    }private:    vector<int> re;};

优化的后序

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    vector<int> postorderTraversal(TreeNode *root) {        stack<TreeNode *> s;        TreeNode *pre = NULL, *cur = root;        while (cur || !s.empty()) {            while (cur) {                s.push(cur);                cur = cur->left;            }            cur = s.top();            if (cur->right && pre != cur->right) {                cur = cur->right;            } else {                re.push_back(cur->val);                pre = cur;                s.pop();                cur = NULL;            }        }        return re;    }    private:    vector<int> re;};




0 0
原创粉丝点击