首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我们能用Morris遍历进行后期排序吗?

我们能用Morris遍历进行后期排序吗?
EN

Stack Overflow用户
提问于 2016-04-03 10:57:40
回答 5查看 10.4K关注 0票数 27

我已经访问了许多网站,但找不到任何算法的莫里斯postOrder遍历。我知道我们可以将Morris算法用于preOrder,如果inOrder.It存在的话,如果有人给我指点postOrder莫里斯算法,它会有很大的帮助。

EN

回答 5

Stack Overflow用户

发布于 2019-06-20 09:30:33

一种更简单的方法是对称地进行与预定morris遍历相反的操作,并以相反的顺序打印节点。

代码语言:javascript
运行
复制
    TreeNode* node = root;
    stack<int> s;
    while(node) {
        if(!node->right) {
            s.push(node->val);
            node = node->left;
        }
        else {
            TreeNode* prev = node->right;

            while(prev->left && prev->left != node)
                prev = prev->left;

            if(!prev->left) {
                prev->left = node;
                s.push(node->val);
                node = node->right;
            }
            else {  
                node = node->left;
                prev->left = NULL;
            }
        }
    }

    while(!s.empty()) {
        cout << s.top() << " ";
        s.pop();
    }

    cout << endl;
票数 5
EN

Stack Overflow用户

发布于 2020-07-23 17:18:01

一旦你理解了它背后的概念,它看起来就很简单。

基本上,我们使用内部遍历( Binary )来打印给定二叉树的后序遍历( given ).我们所需要做的就是反转无序遍历的第二和第三部分,即以L N的方式打印它。

当在线程创建阶段,在前面创建的线程的帮助下再次访问节点时,这意味着我们已经遍历了左边的子树。因此,我们需要打印所有左子树节点。因此,我们打印当前节点的左子节点和右子节点的左子树节点。

在这一步之后,我们已经打印了所有的左节点,现在我们所需要做的就是打印右指针的反向顺序。如果我们认为它是一个简单的单链表,其中下一个指针是右子树中每个节点的正确子节点。

以相反的顺序打印列表,直到当前节点。转到您保存的顺序后继节点,并按照相同的顺序进行操作。

我希望这能让你的事情更清楚些。

PS:链表反转用于反转无序遍历的第二部分和第三部分。

票数 3
EN

Stack Overflow用户

发布于 2018-12-06 05:35:33

我的Java解决方案--它有很多代码注释,但是如果您需要更多的解释,请在这里给我注释。

代码语言:javascript
运行
复制
public static void postOrder(Node root) {
    // ensures all descendants of root that are right-children
    //  (arrived at only by "recurring to right") get inner-threaded
    final Node fakeNode = new Node(0);    // prefer not to give data, but construction requires it as primitive
    fakeNode.left = root;

    Node curOuter = fakeNode;
    while(curOuter != null){    // in addition to termination condition, also prevents fakeNode printing
        if(curOuter.left != null){
            final Node curOuterLeft = curOuter.left;

            // Find in-order predecessor of curOuter
            Node curOuterInOrderPred = curOuterLeft;
            while(curOuterInOrderPred.right != null && curOuterInOrderPred.right != curOuter){
                curOuterInOrderPred = curOuterInOrderPred.right;
            }

            if(curOuterInOrderPred.right == null){
                // [Outer-] Thread curOuterInOrderPred to curOuter
                curOuterInOrderPred.right = curOuter;

                // "Recur" on left
                curOuter = curOuterLeft;

            } else {    // curOuterInOrderPred already [outer-] threaded to curOuter
                        //  -> [coincidentally] therefore curOuterLeft's left subtree is done processing
                // Prep for [inner] threading (which hasn't ever been done yet here)...
                Node curInner = curOuterLeft;
                Node curInnerNext = curInner.right;
                // [Inner-] Thread curOuterLeft [immediately backwards] to curOuter [its parent]
                curOuterLeft.right = curOuter;
                // [Inner-] Thread the same [immediately backwards] for all curLeft descendants
                //  that are right-children (arrived at only by "recurring" to right)
                while(curInnerNext != curOuter){
                    // Advance [inner] Node refs down 1 level (to the right)
                    final Node backThreadPrev = curInner;
                    curInner = curInnerNext;
                    curInnerNext = curInnerNext.right;
                    // Thread immediately backwards
                    curInner.right = backThreadPrev;
                }

                // curInner, and all of its ancestors up to curOuterLeft,
                //  are now indeed back-threaded to each's parent
                // Print them in that order until curOuter
                while(curInner != curOuter){
                    /*
                        -> VISIT
                     */
                    System.out.print(curInner.data + " ");

                    // Move up one level
                    curInner = curInner.right;
                }

                // "Recur" on right
                curOuter = curOuter.right;
            }

        } else {
            // "Recur" on right
            curOuter = curOuter.right;
        }
    }
}

class Node {
  Node left;
  Node right;
  int data;

  Node(int data) {
      this.data = data;
      left = null;
      right = null;
  }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36384599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档