Morris算法、Morris算法的前序 中序 后序遍历及其C++实现

Morris算法遍历二叉树的时间复杂度为O(N),额外的空间复杂度为O(1)

Morris算法的步骤:

当前节点用cur表示

1)如果cur无左孩子,cur向右移动cur=cur->right

2)如果cur有左孩子,找到cur左子树的最右节点,记为mostright:

                 如果mostright的右指针为空 让其指向cur,mostright->right=cur,cur向左移动,cur=cur->left;

                 如果mostright的右指针指向cur 让其指向空 mostright->right=null cur向右移动,cur=cur->right;

如果一个树有左子树,会到达该节点两次,如果没有左子树会到达该节点一次

           1

    2         3

4     5         7

比如上面的二叉树,首先遍历1 1有左子树,找到左子树的最右节点5 5->right=1 cur=cur->left

遍历2 找到2的左子树的最右节点4 4->>right=2 cur=cur->left

遍历4 4没有左子树 cur=cur->right

cur=2 遍历2 2的左子树的最右节点是4 4->right!=null  4->right=null cur=cur->right

遍历5 5没有左子树 cur=cur->right

cur=1 遍历1 1的左子树的最右节点为5 5->right!=null 5->right=null cur=cur->right

cur=3 遍历3 3无左子树 cur=cur->right

cur=7 遍历7

遍历12425136  只有1 2 有左子树 遍历两次 其他的均遍历一次

void morrisIn(TreeNode*head){
        if(head==NULL)
            return;
        TreeNode*cur=head;
        TreeNode*mostRight=NULL;
        while(cur!=NULL){
            mostRight=cur->left;
            if(mostRight!=NULL){//如果有左子树执行
                while(mostRight->right!=NULL&&mostRight->right!=cur){
                    mostRight=mostRight->right;
                }
                if(mostRight->right==NULL){
                    mostRight->right=cur;
                    cur=cur->left;
                    continue;//相当于是cur将会有第二次访问的机会,所以这次不打印 并且左子树没有访问完 继续往下执行
                }else
                {
                    mostRight->right=NULL;
                }
            }
            //std::cout<<cur->val<<" ";
            cur=cur->right;
        }
}

利用morris算法进行前序遍历

使用递归遍历二叉树,所有的节点都访问3次,选择第一次到达该节点时进行打印 前序遍历 第二次 中序遍历 第三次 后序遍历

对于morris算法

如果一个树有左子树,会到达该节点两次,如果没有左子树会到达该节点一次,没有左子树的节点相当于第一次和第二次合二为一

所以前序遍历就是第一次访问该节点的时候

void morrisPre(TreeNode*head){
        if(head==NULL)
            return;
        TreeNode*cur=head;
        TreeNode*mostRight=NULL;
        while(cur!=NULL)
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值