二叉树的遍历
2016-06-03 15:57
274 查看
转载请注明 t1234xy4 原创:http://blog.csdn.net/t1234xy4/article/details/51579416
二叉树的遍历:
源码下载点:http://download.csdn.net/detail/t1234xy4/9540560
二叉树的遍历有递归与非递归之分,使用非递归的遍历在性能上和健壮性上都优于递归。通常能使用非递归的情况下,都不用递归。
二叉树的遍历分为 先序、中序、后序遍历
使用递归的实现代码极其简单
先序:BinaryTreeDLR
中序:
后序:
使用非递归遍历相对比较复杂,我来总结一下需要注意的点和非递归的方法:
先序:
1、使用一个栈saveReturnNode,我的想法是保存当前节点的右节点,如果存在。
中序:
1、使用一个saveReturnNode栈保存当前节点,令一个bool isPop来判定是否取至于栈;存在左子树就压栈,遇到叶子节点就开始退栈;然后检查每个退栈的节点是否有右子树。
很凌乱,只要记住:1、使用栈保存当前节点;2、使用一个bool判定是否遍历过;
后序:
后序遍历需要特别注意:1、栈saveReturnNode保存当前节点;2、需要记住上一次遍历的节点Pre,如果root存在右子树且Pre == root->right ;则说明已经遍历过了右子树,此时应该退栈。
自己实现的代码,难免会存在错误和bug,希望广大网友在学习的时候发现了在下面指出来,让其他人少走弯路!
二叉树的遍历:
源码下载点:http://download.csdn.net/detail/t1234xy4/9540560
二叉树的遍历有递归与非递归之分,使用非递归的遍历在性能上和健壮性上都优于递归。通常能使用非递归的情况下,都不用递归。
二叉树的遍历分为 先序、中序、后序遍历
使用递归的实现代码极其简单
先序:BinaryTreeDLR
void BinaryTreeDLR(BinaryTreeNode* root) { if(root == NULL) return ; printf("%4d",root->m_Value); BinaryTreeDLR(root->m_pLeft); BinaryTreeDLR(root->m_pRight); }
中序:
<pre name="code" class="cpp">void BinaryTreeLRD(BinaryTreeNode* root) { if(root == NULL) return ; BinaryTreeLRD(root->m_pLeft); BinaryTreeLRD(root->m_pRight); printf("%4d",root->m_Value); }
后序:
void BinaryTreeLRD(BinaryTreeNode* root) { if(root == NULL) return; BinaryTreeLRD(root->m_pLeft); BinaryTreeLRD(root->m_pRight); printf("%4d",root->m_Value); }
使用非递归遍历相对比较复杂,我来总结一下需要注意的点和非递归的方法:
先序:
1、使用一个栈saveReturnNode,我的想法是保存当前节点的右节点,如果存在。
void BinaryTreeDLRNoRecursion(BinaryTreeNode* root) { if(root == NULL) return ; std::stack<BinaryTreeNode*> saveReturnNode; while(root != NULL || !saveReturnNode.empty()) { if(root == NULL){ root = saveReturnNode.top(); saveReturnNode.pop(); } printf("%4d",root->m_Value); //D if(root->m_pRight!=NULL) saveReturnNode.push(root->m_pRight); //R root = root->m_pLeft;//L } }
中序:
1、使用一个saveReturnNode栈保存当前节点,令一个bool isPop来判定是否取至于栈;存在左子树就压栈,遇到叶子节点就开始退栈;然后检查每个退栈的节点是否有右子树。
很凌乱,只要记住:1、使用栈保存当前节点;2、使用一个bool判定是否遍历过;
void BinaryTreeLDRNoRecursion(BinaryTreeNode* root) { if(root == NULL) return ; std::stack<BinaryTreeNode*> saveReturnNode; bool isPop = false; while (root != NULL || !saveReturnNode.empty()) { if(root == NULL){ root = saveReturnNode.top(); saveReturnNode.pop(); isPop = true; } if(root->m_pLeft!=NULL && !isPop){ saveReturnNode.push(root); root = root->m_pLeft; isPop = false; }else { printf("%4d",root->m_Value); root = (root->m_pRight)?(root->m_pRight):NULL; isPop =false; } } }2、利用中序遍历的顺序,来记住遍历方法。1、遇到存在左子树的压栈;2、访问节点在退栈之前 ;3 退栈后检查再是否存在右节点,存在进入右节点
void BinaryTreeLDRNoRecursion2(BinaryTreeNode* root) { if (root == NULL) return; std::stack<BinaryTreeNode*> saveReturnNode; while(root!=NULL || !saveReturnNode.empty()) { if (root == NULL) { root = saveReturnNode.top(); printf("%4d",root->m_Value); saveReturnNode.pop(); root = (root->m_pRight)?(root->m_pRight):NULL; }else { saveReturnNode.push(root); root = root->m_pLeft; } } }
后序:
后序遍历需要特别注意:1、栈saveReturnNode保存当前节点;2、需要记住上一次遍历的节点Pre,如果root存在右子树且Pre == root->right ;则说明已经遍历过了右子树,此时应该退栈。
void BinaryTreeLRDNoRecursion(BinaryTreeNode* root) { if(root == NULL) return ; std::stack<BinaryTreeNode *> saveNode; BinaryTreeNode* Pre = NULL; while(root!=NULL || !saveNode.empty()) { if (root == NULL) { root = saveNode.top(); if(root->m_pRight != NULL && root->m_pRight!=Pre ) root = root->m_pRight; else { Pre = root; printf("%4d",root->m_Value); saveNode.pop(); root = NULL; } }else { saveNode.push(root); root = root->m_pLeft; } } }
自己实现的代码,难免会存在错误和bug,希望广大网友在学习的时候发现了在下面指出来,让其他人少走弯路!
相关文章推荐
- RobotFramework自动化测试之脚本编写(一)
- To-do List
- postgresql 数据库 中间件 pgoneproxy
- Python IDE Tools
- WebUtils-网络请求工具类
- ngrok 本机代码部署外网访问神器
- Window 下 Qt5 使用QMediaplayer 进行视频播放 流播放问题
- 使用httpclient实现上传下载(javaWeb系统数据传输http实现)
- python中if __name__ == '__main__': 的解析
- 执行程序---system
- PL/sql使用总结
- 诚信与道德
- QT moc 学习小结
- C题目
- CUDA 和opencv安装问题
- Android图像处理(四)Xfermode和BitmapShader
- 常用内建异常类
- [bzoj1008][HNOI2008]越狱
- CSS list-style 属性
- 实现MyString类--构造函数、拷贝构造函数、析构函数、赋值函数、操作符重载函数