首先谈谈树的三种遍历方式:
/** * 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: void inorder(TreeNode* root, vector<int>& vec) { if(root->left != NULL) inorder(root->left, vec); // 左 vec.push_back(root->val); // 根 if(root->right != NULL) inorder(root->right, vec); // 右 } vector<int> inorderTraversal(TreeNode* root) { vector<int> vec; if(root == NULL) return vec; inorder(root, vec); return vec; } };
/** * 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: vector<int> inorderTraversal(TreeNode* root) { vector<int> vec; if(root == NULL) return vec; stack<TreeNode*> st; TreeNode *cur = root; while(!st.empty() || cur != NULL) { while(cur != NULL) { //不断先将左子树节点加入栈 st.push(cur); cur = cur->left; } cur = st.top(); st.pop(); vec.push_back(cur->val); cur = cur->right; } return vec; } };
/** * 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: vector<int> inorderTraversal(TreeNode* root) { vector<int> vec; if(root == NULL) return vec; TreeNode* cur = root; TreeNode* prev = NULL; while(cur) { // 如果当前左孩子为空,则其直接输出,并遍历设立右孩子为遍历节点 if(cur->left == NULL) { vec.push_back(cur->val); cur = cur->right; continue; } // 如果左孩子不为空 prev = cur->left; // 找到左孩子中的最右节点,也就是左子树值最大的节点 while(prev->right != NULL && prev->right != cur) prev = prev->right; // 如果左子树值最大节点的右孩子为空,那么就将其指向当前cur,这样在下次遍历到 // 此节点时,我们可以直接回溯到比左子树最大节点的下一个节点,也就是cur if(prev->right == NULL) { prev->right = cur; cur = cur->left; } // 如果当前已经指向了最右节点,那么此时说明已经遍历到了此节点,要还原二叉树 // 因为原本指向的right的为NULL,并将cur回溯到原本的左子树位置。 else { prev->right = NULL; vec.push_back(cur->val); cur = cur->right; } } return vec; } };