Morris遍历以及Morris前序中序后序遍历实现

Posted darkif

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Morris遍历以及Morris前序中序后序遍历实现相关的知识,希望对你有一定的参考价值。

技术图片

技术图片
#include<iostream>
using namespace std;

struct TreeNode{
    int val;
    TreeNode* right;
    TreeNode* left;
    TreeNode(int _val):val(_val),right(nullptr),left(nullptr){}
};

void Morris(TreeNode* root){
     if(root == nullptr)
           return;
     TreeNode* cur=root;
     TreeNode* mostRight=nullptr;

    //当cur为空停止,即上图中的情况3
     while(cur != nullptr){
         mostRight=cur->left;
         //如果mostRight!=nullptr,进入情况2
         if(mostRight != nullptr){
              while(mostRight->right && mostRight != cur)
                      mostRight=mostRight->right; 
              //当mostRight == nullptr,即情况2.a
              if(mostRight->right == nullptr){
                      mostRight->right=cur;
                      cur=cur->left;
                      continue;
              }
              else{             //当mostRight == cur,即情况2.b
                    mostRight->right=nullptr;
                     /*cur=cur->left;
                     continue;*/
               }
         }
          //mostright为空进入情况1
          cur=cur->left;  
    }
}    
View Code

 

Morris前序遍历

有左子树就会回到cur节点两次,没有就来一次

void MorrisPre(TreeNode* root) {
    if (root == nullptr)
        return;
    TreeNode* cur = root;
    TreeNode* mostRight = nullptr;

    while (cur != nullptr) {
        mostRight = cur->left;

        if (mostRight != nullptr) {
            while (mostRight->right && mostRight->right != cur) {
                mostRight = mostRight->right;
            }

            if (mostRight->right == nullptr) {        
                //第一次到达左子树的最右子树
                printf("%d ", cur->val);
                mostRight->right = cur;
                cur = cur->left;
                continue;
            }
            else {                                    
                //第二次到达左子树的最右子树 
                mostRight->right == cur;
                mostRight->right = nullptr;
                /*cur = cur->right;
                continue;*/
            }
        }
        else {        
            //当前cur只能来一次
            printf("%d ", cur->val);
        }

        cur = cur->right;
    }
}

 

Morris中序遍历

 

void MorrisIn(TreeNode* root) {
    if (root == nullptr)
        return;
    TreeNode* cur = root;
    TreeNode* mostRight = nullptr;

    while (cur != nullptr) {
        mostRight = cur->left;

        if (mostRight != nullptr) {
            while (mostRight->right && mostRight->right != cur) {
                mostRight = mostRight->right;
            }

            if (mostRight->right == nullptr) {        //第一次到达左子树的最右子树
                mostRight->right = cur;
                cur = cur->left;
                continue;
            }
            else {                                    //第二次到达左子树的最右子树 mostRight->right == cur;
                mostRight->right = nullptr;
                /*cur = cur->right;
                continue;*/
            }
        }

        //往右移动的时候打印
        printf("%d ", cur->val);
        cur = cur->right;
    }
}

 

Morris后序遍历

//右孩子指向上一个节点
TreeNode* ReverseNode(TreeNode* node) {
    TreeNode* pre = nullptr;
    TreeNode* next = nullptr;
    while (node) {
        next = node->right;
        node->right = pre;
        pre = node;
        node = next;
    }
    return pre;
}

//逆序打印左孩子的右边界
void PrintNode(TreeNode* node) {
    TreeNode* tail = ReverseNode(node);
    TreeNode* cur = tail;
    while (cur) {
        printf("%d ", cur->val);
        cur = cur->right;
    }
    ReverseNode(tail);        //还原
}


void MorrisPos(TreeNode* root) {
    if (root == nullptr)
        return;
    TreeNode* cur = root;
    TreeNode* mostRight = nullptr;

    while (cur != nullptr) {
        mostRight = cur->left;

        if (mostRight != nullptr) {
            while (mostRight->right && mostRight->right != cur) {
                mostRight = mostRight->right;
            }

            if (mostRight->right == nullptr) {        //第一次到达左子树的最右子树
                mostRight->right = cur;
                cur = cur->left;
                continue;
            }
            else {                                    //第二次到达左子树的最右子树 mostRight->right == cur;
                mostRight->right = nullptr;

                //逆序打印左子树的右边界
                PrintNode(cur->left);
            }
        }
        cur = cur->right;
    }

    PrintNode(root);
}

 

以上是关于Morris遍历以及Morris前序中序后序遍历实现的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的四种遍历方式以及中序后序前序中序前序后序层序创建二叉树专为力扣刷题而打造

二叉树的四种遍历方式以及中序后序前序中序前序后序层序创建二叉树专为力扣刷题而打造

二叉树的前序中序后序遍历相互求法

二叉树遍历(前序中序后序层次深度优先广度优先遍历)

已知前序中序求后续;已知中序后序求前序;

二叉树前序中序后序遍历相互求法