二叉树的先跟遍历,中跟遍历,后根遍历

  1. //二叉树结点的定义。  
  2. typedef struct BiTreeNode  
  3. {  
  4.     int data;  
  5.     BiTreeNode* left;  
  6.     BiTreeNode* right;  
  7. public:  
  8.     BiTreeNode();//定义了一个结构体的构造函数。  
  9. }BiTreeNode,*LinkBiTree;  
  10.   
  11. //构造函数的实现  
  12. BiTreeNode::BiTreeNode()  
  13. {  
  14.     left = NULL;  
  15.     right = NULL;  
  16. }  
  1. int SqBiTree::PreOrderTraverse(LinkBiTree root)  
  2. {  
  3.     LinkBiTree p = root;  
  4.     Stack stack;//定义一个栈  
  5.     stack.InitStack();//栈初始化  
  6.     cout<<"The Tree is ..."<<endl;  
  7.       
  8.     while(!stack.IsEmpty() || p != NULL)  
  9.     {  
  10.                 //从头结点开始遍历到左子树最左边的叶子节点。把每一个遍历的节点入栈,用于准备遍历其相应的右子树  
  11.         while (p!=NULL)  
  12.         {  
  13.             cout<<p->data<<"  ";//访问节点  
  14.             stack.Push(p);  
  15.             p = p->left;  
  16.         }  
  17.         stack.Pop(p);  
  18.                   //先一个循环遍历相应节点的右子树  
  19.         p = p->right;  
  20.       
  21.     }  
  22.     cout<<endl;  
  23.     return 0;  
  24. }  

  1. //中根遍历的非递归算法  
  2. int SqBiTree::InOrderTraverse(LinkBiTree root)  
  3. {  
  4.     LinkBiTree p = root;  
  5.     Stack stack;  
  6.     stack.InitStack();  
  7.     cout<<"The Tree is ..."<<endl;  
  8.       
  9.     while(!stack.IsEmpty() || p != NULL)  
  10.     {  
  11.                   //从根节点开始到最左边的叶子节点,入栈  
  12.         while (p!=NULL)  
  13.         {  
  14.             stack.Push(p);  
  15.             p = p->left;  
  16.         }  
  17.         stack.Pop(p);  
  18.         cout<<p->data<<"  "//访问节点  
  19.         p = p->right; //下一次循环把节点p的右子树入栈  
  20.     }  
  21.     cout<<endl;  
  22.     return 0;  
  23. }  

  1. //后根遍历的非递归算法  
  2. int SqBiTree::PostOrderTraverse(LinkBiTree root)  
  3. {  
  4.     LinkBiTree p = root;  
  5.     Stack stack;  
  6.     stack.InitStack();  
  7.   
  8.     while(!stack.IsEmpty() || p != NULL)  
  9.     {         
  10.                 //从根节点开始到最左边的叶子节点,入栈  
  11.         while (p!=NULL)  
  12.         {        
  13.             stack.Push(p,1);  
  14.             p = p->left;  
  15.         }  
  16.         int skip = 0;  
  17.         stack.Pop(p,skip);  
  18.         if (skip == 0)  
  19.         {  
  20.             cout<<p->data<<"  ";  
  21.             p = NULL;  
  22.         }  
  23.         else if (skip == 1)  
  24.         {  
  25.             p =p->right;  
  26.         }  
  27.     }  
  28.     return 0;  
  29. }  

后根遍历用到的栈有一些特殊,栈中元素要出栈两次才会被真正出栈。也就是说:

该栈的链式存储节点的定义如下:

[cpp]  view plain copy
  1. typedef struct StackNode  
  2. {  
  3.     LinkBiTree data;//数据域  
  4.     int skip; //出栈操作被“忽略”的次数  
  5.     StackNode *next;//指向下一结点的指针域  
  6. public:  
  7.     StackNode();  
  8. }StackNode,*LinkList;  

例如:

栈的某个节点的skip = 0时,只需执行一次出栈操作即可正常出栈。

栈的某个节点的skip = 1时,第一次出栈操作只会返回该节点数据域中的数据,第二次出栈操作才会真正的出栈(当然数据域中的数据也返回)

栈的某个节点的skip = 2时,前两次出栈操作只会返回该节点数据域中的数据,第三次出栈操作才会真正的出栈(当然数据域中的数据也返回)

......

 

通过比较二叉树的先根遍历,中根遍历,后根遍历的非递归算法可以发现:这三个算法的实现是极其相似的(如同它们递归算法的也很相似一般)。

1:都用到了栈来暂存节点。

2:都是两个while的嵌套循环。

3: 如果除去访问节点的语句,先根遍历和中根遍历是完全相同的,后根遍历也只是出栈函数的参数不同而已。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值