二叉树的遍历
来源:互联网 发布:志愿者面试 知乎 编辑:程序博客网 时间:2024/05/23 15:12
转载请注明 t1234xy4 原创:http://blog.csdn.net/t1234xy4/article/details/51579416
二叉树的遍历:
源码下载点: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); //Dif(root->m_pRight!=NULL)saveReturnNode.push(root->m_pRight); //Rroot = 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,希望广大网友在学习的时候发现了在下面指出来,让其他人少走弯路!
0 0
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- 二叉树的遍历
- win7配置Apache+php+mysql
- Android Fragment完全解析,关于碎片你所需知道的一切
- WebService之WSDL文档元素详解 (转)
- Entity Framework Code First (二)Custom Conventions
- 关于ArrayList与LinkedList添加数据的效率问题
- 二叉树的遍历
- 单元格左侧附带选择按钮
- image按钮高度和宽度属性
- Entity Framework Code First (三)Data Annotations
- MyBatis转义
- AndroidAnnotations框架详解
- redis3.0配置调优
- JavaScript中的函数节流
- java 异常处理 Throwable Error 和Exception