码迷,mamicode.com
首页 > 其他好文 > 详细

追寻伯利恒二叉树 -- 不用栈不用递归

时间:2016-04-19 15:41:20      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

http://www.acmerblog.com/inorder-tree-traversal-without-recursion-and-without-stack-5988.html

 

用叶子节点的空指针来记录当前节点的位置,然后一旦遍历到了叶子节点,发现叶子节点的右指针指向的是当前节点,那么就认为以当前节点的左子树已经遍历完成。

 

以inorder为例,初始化当前节点为root,它的遍历规则如下:

  • 如果当前节点为空,程序退出。
  • 如果当前节点非空,
    • 如果当前节点的左儿子为空,那么输出当前节点,当前节点重置为当前节点的右儿子。
    • 如果当前节点的左儿子非空,找到当前节点左子树的最右叶子节点(此时最右节点的右儿子有两种情况,一种是指向当前节点,一种是为空,你也许感到奇怪,右节点的右儿子怎么可能非空,注意,这里的最右叶子节点只带的是原树中的最右叶子节点。),若其最右叶子节点为空,令其指向当前节点,将当前节点重置为其左儿子,若其最右节点指向当前节点,输出当前节点,将当前节点重置为当前节点的右儿子,并恢复树结构,即将最右节点的右节点再次设置为NULL。

 

#include<stdio.h>
#include<stdlib.h>

struct tNode
{
   int data;
   struct tNode* left;
   struct tNode* right;
};

void MorrisTraversal(struct tNode *root)
{
  struct tNode *current,*pre;

  if(root == NULL)
     return; 

  current = root;
  while(current != NULL)
  {                 
    if(current->left == NULL)
    {
      printf(" %d ", current->data);
      current = current->right;      
    }    
    else
    {
      /* 找到current的前驱节点 */
      pre = current->left;
      while(pre->right != NULL && pre->right != current)
        pre = pre->right;

      /* 将current节点作为其前驱节点的右孩子 */
      if(pre->right == NULL)
      {
        pre->right = current;
        current = current->left;
      }

      /* 恢复树的原有结构,更改right 指针 */   
      else 
      {
        pre->right = NULL;
        printf(" %d ",current->data);
        current = current->right;      
      } /* End of if condition pre->right == NULL */
    } /* End of if condition current->left == NULL*/
  } /* End of while */
}

struct tNode* newtNode(int data)
{
  struct tNode* tNode = (struct tNode*)
                       malloc(sizeof(struct tNode));
  tNode->data = data;
  tNode->left = NULL;
  tNode->right = NULL;

  return(tNode);
}

/* 测试*/
int main()
{

  /* 构建树结构如下:
            1
          /           2      3
      /      4     5
  */
  struct tNode *root = newtNode(1);
  root->left        = newtNode(2);
  root->right       = newtNode(3);
  root->left->left  = newtNode(4);
  root->left->right = newtNode(5); 

  MorrisTraversal(root);
   return 0;
}

 

追寻伯利恒二叉树 -- 不用栈不用递归

标签:

原文地址:http://www.cnblogs.com/argenbarbie/p/5408438.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!