二叉树遍历模板之Morris

二叉树遍历模板之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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值