数据结构——不用栈、不用递归中序遍历树

原文地址:Inorder Tree Traversal without recursion and without stack!

用Morris Traversal,我们可以不用递归和栈遍历树。Morris Traversal的思想是基于线索二叉树的。在这个遍历中,我们首先建立到中序先驱的连接,并用这些连接打印数据,最后恢复变化,还原出树的原貌。

1. 初始化current为root 
2. While current不为NULL
   If current没有左孩子
      a) 打印current的值
      b) 跳到right,比如:current = current->right
   Else
      a) 使current作为在current的左子树中最右节点的右孩子
      b) 跳到left孩子,比如:current = current->left

尽管遍历的过程中改变了树,但是活干完以后原形状的树还是会被还原出来的。不像基于栈的遍历,这种遍历不需要额外的空间。

/* A binary tree tNode has data, pointer to left child
   and a pointer to right child */
class tNode 
{
    int data;
    tNode left, right;

    tNode(int item) 
    {
        data = item;
        left = right = null;
    }
}

class BinaryTree 
{
    tNode root;

    /* Function to traverse binary tree without recursion and 
       without stack */
    void MorrisTraversal(tNode root) {
        tNode current, pre;

        if (root == null)
            return;

        current = root;
        while (current != null) 
        {
            if (current.left == null) 
            {
                System.out.print(current.data + " ");
                current = current.right;
            }
            else
            {
                /* Find the inorder predecessor of current */
                pre = current.left;
                while (pre.right != null && pre.right != current) 
                    pre = pre.right;

                /* Make current as right child of its inorder predecessor */
                if (pre.right == null) 
                {
                    pre.right = current;
                    current = current.left;
                } 

                 /* Revert the changes made in if part to restore the 
                    original tree i.e.,fix the right child of predecssor*/
                 else
                 {
                    pre.right = null;
                    System.out.print(current.data + " ");
                    current = current.right;
                }   /* End of if condition pre->right == NULL */

            } /* End of if condition current->left == NULL*/

        } /* End of while */

    }

    public static void main(String args[]) 
    {
        /* Constructed binary tree is
               1
             /   \
            2      3
          /  \
        4     5
        */
        BinaryTree tree = new BinaryTree();
        tree.root = new tNode(1);
        tree.root.left = new tNode(2);
        tree.root.right = new tNode(3);
        tree.root.left.left = new tNode(4);
        tree.root.left.right = new tNode(5);

        tree.MorrisTraversal(tree.root);
    }
}

// This code has been contributed by Mayank Jaiswal(mayank_24)

输出:

4 2 5 1 3

参考文献:

www.liacs.nl/~deutz/DS/september28.pdf
http://comsci.liu.edu/~murali/algo/Morris.htm
www.scss.tcd.ie/disciplines/software_systems/…/HughGibbonsSlides.pdf

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值