目录
二叉树遍历模板之Morris(Java&CPP)
方法说明
有一种巧妙的方法可以在线性时间内,只占用常数空间来实现二叉树的前序、中序、和后序遍历。这种方法由 J. H. Morris 在 1979 年的论文「Traversing Binary Trees Simply and Cheaply」中首次提出,因此被称为 Morris 遍历。
Morris遍历的核心思想是利用树的大量空闲指针,实现空间开销的极限缩减。
Morris遍历的核心技巧就是利用空闲指针来建立前驱节点和当前节点之间的线索。
时间复杂度为O(n),空间复杂度为O(1)
前序遍历
题目
144. Binary Tree Preorder Traversal
算法步骤
1.初始化根节点为cur;
2. 如果当前节点的左子节点为空,则遍历当前节点,并转到右子节点;
3. 如果当前节点的左子节点不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点;
(1) 如果前驱节点的右子节点为空,将前驱节点的右子节点设置为当前节点,遍历当前节点后更新为当前节点的左子节点。
(2) 如果前驱节点的右子节点为当前节点,将它的右子节点重新设为空。当前节点更新为当前节点的右子节点。
4. 重复步骤 2 和步骤 3,直到遍历结束。
代码实现
C++代码如下:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
TreeNode *cur=root, *prev=nullptr;
while(cur!=nullptr){
if(cur->left==nullptr){
result.push_back(cur->val);
prev = cur;
cur = cur->right;
}
else{
TreeNode *node = cur->left;
while(node->right!=nullptr&&node->right!=cur){
node = node->right;
}
if(node->right==nullptr){
result.push_back(cur->val);
prev = cur;
node->right = cur;
cur=cur->left;
}
else{
node->right = nullptr;
cur = cur->right;
}
}
}
return result;
}
Java代码如下:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<Integer>();
TreeNode cur = root;
while(cur != null){
if(cur.left==null){
result.add(cur.val);
cur = cur.right;
}else