二叉树遍历
依据根节点的访问次序分为先序遍历、中序遍历、后序遍历、层序遍历。中序遍历即以左节点、根节点、右节点的顺序遍历,根节点放在中间,其它方式依此类推。下面介绍三种中序遍历算法。
递归
递归法简单明了,但是效率较低。下面为中序遍历,前序遍历和后序遍历同理。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
void inorderTraversal(TreeNode* root, vector<int>& list){
if(root != NULL){
inorderTraversal(root->left, list);
list.push_back(root->val);
inorderTraversal(root->right, list);
}
}
栈方法
-
前序遍历
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
vector<TreeNode*> stk;
TreeNode* cur = root;
while(cur != NULL || stk.size() != 0){
if(cur != NULL) {
res.push_back(cur->val);
stk.push_back(cur);
cur = cur->left;
}
else {
cur = stk.back();
stk.pop_back();
cur = cur->right;
}
}
return res;
}
-
中序遍历
vector<int> inorderTraversal(TreeNode* root) { vector<int> res; vector<TreeNode*> stk; TreeNode* cur = root; while(cur != NULL || stk.size() != 0){ if(cur != NULL) { stk.push_back(cur); cur = cur->left; } else { cur = stk.back(); res.push_back(cur->val); stk.pop_back(); cur = cur->right; } } return res; }
-
后续遍历
vector<int> postorderTraversal(TreeNode* root) { vector<int> res; if(root == NULL) return res; stack<TreeNode*> tree; while(root != NULL || tree.size() != 0) { if(root != NULL) { tree.push(root); res.insert(res.begin(), root->val); //因为是后续遍历,节点需要从队头插入,并且先遍历右子树,加入的顺序是中-右-左,这样最终的顺序就是左-右-中 root = root->right; } else { root = tree.top()->left; tree.pop(); } } return res; }
莫里斯遍历
该方法通过设置根节点作为其前驱节点的右孩子,来构造线索二叉树,这样在遍历完左子树时,遍历前驱结点的右孩子就可以跳转到根节点继续遍历右子树。下面是中序遍历实现,前序遍历通过更改res.push_back()的位置即可,后续遍历可以用上述思想,将前序遍历修改为头部插入,并且先遍历右子树。
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode* pre;
while(root){
if(root->left){
pre = root->left;
while(pre->right && pre->right != root) pre = pre->right;
if(pre->right == NULL){ //说明root第一次作为当前根节点出现,其左子树没有遍历过,则为其前驱结点设置线索,进入左子树。
pre->right = root;
root = root->left;
continue;
}
//说明root是通过前驱结点->right跳转到的,左子树已经遍历完成,需要删除线索,进入右子树。
pre->right = NULL;
res.push_back(root->val);
root = root->right;
}
else{
res.push_back(root->val);
root = root->right;
}
}
return res;
}