• 二叉树遍历的三种方法(以中序为例)


     二叉树遍历的三种方法

    递归 简单 时间O(n) 空间O(n)
    非递归+栈 中等 时间O(n) 空间O(n)
    非递归、不用栈 中等 时间O(n) 空间O(1)

    伪代码实现--近C++代码

    方法一:递归

    1 Inorder-Tree-Walk(x)
    2     if(x != NULL)
    3         Inorder-Tree-Walk(x->left)
    4         print x->key
    5         Inorder-Tree-Walk(x->right)

    方法二:非递归+栈

     1 Inorder-Tree-Walk(x)
     2     stack<Node*> s //定义装二叉树节点指针的栈容器
     3         while(x != NULL || !s.empty())
     4              if(x != NULL)
     5                  s.push(x)
     6                  x = x->left
     7              else if(!s.empty())
     8                  x = s.top()
     9                  s.pop()
    10                  print x->key
    11                  x = x->right  

    方法三:非递归,不用栈(Morris 中序遍历[1])

    思想:利用线索二叉树的思想,无右子树的节点的空闲的右指针,指向此节点中序遍历的后继,以此记录在此节点之后要访问的点。要使得无右子树的节点指向后继,不直接计算其后继,而是迭代地计算所经过的节点的前驱(左子树的最右节点)。

     1 Inorder-Tree-Walk(x)
     2     Node *cur = x, *prev;
     3     while(cur != NULL)
     4         if(cur->left != NULL)  //如果左子树不为空,不应打印当前节点,需在当前节点的前驱节点记录下此节点(此节点记录在其前驱的右指针,其前驱右指针原本一定为空),方便下次找到这个节点。
     5             //试图找到当前节点的中序序列前驱,前驱在左子树的最右点
     6             prev = cur->left  //先使prev为左子树根节点
     7             while(prev->right != NULL && prev->right != cur)
     8                 prev = prev->right
     9             //第一次找到左子树最右点时,最右点的右指针肯定为空,但是此时将标记其右指针指向该节点的后继(cur 节点),那么第二次到cur时,将再次执行找到其前驱。如果在寻找其前驱的过程中发现:有一个节点指向cur。说明这是第二次访问这个节点(cur的前驱已经打印输出,该cur输出了),这也是为什么找前驱的while里需要判断“prev->right != cur”。
    10             if(prev->right == NULL) //第一次找到cur的前驱prev
    11                 prev->right = cur   //标记其右指针指向cur,因为cur还没有输出,在输出prev后,输出cur
               cur = cur->left //转向左节点,继续循环
    12 else // 第二次找到cur的前驱,此时prev->right == cur。第二次到达cur节点,一定是从其前驱的右指针过来的,说明其前驱已经输出打印完毕,该打印cur了 13 print cur->key
               prev->right = NULL //将原先的标记(右指针指向后继)清除
    14 cur = cur->right //往右走,其左子树和当前节点已经遍历完成,继续循环 15 else //cur->left == NULL, 如果左子树为空,打印输出当前节点 16 print cur->key 17 cur = cur->right //转向右节点,继续循环


    参考资料:[1]
    http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html Accessed at 2015/4/11
         [2] 《算法导论》中文版 原书第三版 机械工业出版社
    
    
  • 相关阅读:
    BroadcastReceiver之发送自定义无序广播
    BroadcastReceiver之应用卸载和安装监听
    Android几种打开SQLite的方法
    BroadcoastReceiver之短信到来监听和获取内容
    BroadcastReceiver之SD的挂载监听
    BroadcastReceive之ip拨号
    Activity之多启动图标
    Uwp Windows10获取设备位置(经纬度)
    DeviceFamily XAML Views(一)
    [SCOI2010]生成字符串
  • 原文地址:https://www.cnblogs.com/xzd1575/p/4417706.html
Copyright © 2020-2023  润新知