二叉树的遍历<递归算法实现>、<非递归算法实现>
来源:互联网 发布:淘宝可以买到美沙酮吗 编辑:程序博客网 时间:2024/06/11 05:10
二叉树的遍历主要有三种:前序遍历、中序遍历、后序遍历
下面以遍历下颗树为例:
前序遍历:-+a*b-cd/ef
中序遍历:a+b*c-d-e/f
后序遍历:abcd-*+ef/-
递归算法实现
public: //前序遍历 void preOrder(void(*visit)(BinTreeNode<T> *p)) { //递归算法 preOrder(root,visit); } //中序遍历 void inOrder(void(*visit)(BinTreeNode<T> *p)) { inOrder(root,visit); } //后序遍历 void postOrder(void(*visit)(BinTreeNode<T> *p)) { postOrder(root,visit); }protected://前序遍历 void preOrder(BinTreeNode<T>*subTree,void(*visit)(BinTreeNode<T> *p)) { if(subTree!=NULL) { visit(subTree); preOrder(subTree->leftChild,visit); preOrder(subTree->rightChild,visit); } } //中序遍历 void inOrder(BinTreeNode<T> *subTree,void(*visit)(BinTreeNode<T> *p)) { //递归函数,=NULL是终止递归条件 if(subTree!=NULL) { inOrder(subTree->leftChild,visit); visit(subTree);//访问根节点 inOrder(subTree->rightChild,visit); } } //后序遍历 void postOrder(BinTreeNode<T> *subTree,void(*visit)(BinTreeNode<T> *p)) { if(subTree!=NULL) { postOrder(subTree->leftChild,visit); postOrder(subTree->rightChild,visit); visit(subTree); } }
非递归算法实现
//每一次访问一个节点后,在向左子树遍历下去之前,//利用这个栈记录该节点的右子女(如果有的话)节点地址,//以便左子树退回时可以直接从栈中取出右子树的根节点,继续其右子树的前序遍历 void preOrder(void(*visit)(BinTreeNode<T> *p)) { stack<BinTreeNode<T> *> nodes; BinTreeNode<T> *temp=root; nodes.push(NULL); while(temp!=NULL) { visit(temp); if(temp->rightChild!=NULL) { nodes.push(temp->rightChild); } if(temp->leftChild!=NULL) { temp=temp->leftChild; } else { temp=nodes.top(); nodes.pop(); } } } //中序遍历 //在一棵子树中首先访问的是中序下的第一个节点 //它位于从根开始的沿着leftchild链走到最左下角的节点,该节点的leftchild为NULL。 //访问完他的数据之后,再遍历它的右子树。如果此右子树又是二叉树,则重复上面的过程,直到该子树遍历完毕。 void inOrder(void(*visit)(BinTreeNode<T> *p)) { stack<BinTreeNode<T> *> nodes; //遍历指针,从根节点开始 BinTreeNode<T> *temp=root; do { //遍历指针未到最左下的节点,不空 while(NULL!=temp) { //该子树沿途节点进栈 nodes.push(temp); temp=temp->leftChild; } if(!nodes.empty()) { //栈不为空的时候退栈,访问根节点,遍历指针进入右子女节点 temp=nodes.top(); visit(temp); nodes.pop(); temp=temp->rightChild; } } while(NULL!=temp||!nodes.empty()); } //后序遍历 //后序遍历比先前的两种遍历要复杂得多,在遍历完左子树之后还不能访问根节点, //需要再遍历右子树,等到右子树遍历完毕之后才能访问根节点。所以在栈工作记录中一定先表明刚才是在左子树<1>还是在右子树<2>中。 //首先使用栈暂存根节点的地址,再向左子树遍历下去,此时根节点的tag为1,当访问完根节点的左子树之后从左子树退回,还要去遍历右子树 //此时改跟的tag为2. //从右子树中退出时才能访问位于栈顶的根节点的值。 void postOrder(void(*visit)(BinTreeNode<T> *p)) { stack<stacknode<T> > nodes; stacknode<T> temp; BinTreeNode<T> *p=root; do { while(NULL!=p) { temp.ptr=p; temp.tag=1; nodes.push(temp); p=p->leftChild; } int continue1=1; while(continue1&&!nodes.empty()) { temp=nodes.top(); nodes.pop(); p=temp.ptr; switch(temp.tag) { case 1: temp.tag=2; nodes.push(temp); continue1=0; p=p->rightChild; break; case 2: visit(p); break; } } } while(!nodes.empty()); } //层次遍历 //层次遍历从二叉树的根节点开始,自上向下,自左向右,分层依次访问树中的各个节点、 void levelOrder(void (*visit)(BinTreeNode<T> *p)) { queue<BinTreeNode<T> *> nodes; BinTreeNode<T> *temp=root; BinTreeNode<T> *tnode; nodes.push(temp); while(!nodes.empty()) { tnode=nodes.front(); nodes.pop(); visit(tnode); if(NULL!=tnode->leftChild) { nodes.push(tnode->leftChild); } if(NULL!=tnode->rightChild) { nodes.push(tnode->rightChild); } } }
需要整个工程的完整项目的朋友可以看我的这篇文章,点击进行跳转
0 0
- 二叉树的递归遍历与非递归算法实现
- 二叉树的递归遍历与非递归算法实现
- 《算法导论》二叉树遍历的递归&非递归实现
- 二叉树遍历的非递归算法的实现
- 二叉树遍历算法实现(递归、非递归)
- 算法:C++实现二叉树遍历(递归、非递归)
- 数据结构----二叉树遍历的非递归算法实现
- 用C++实现的二叉树非递归遍历算法
- 二叉树的遍历<递归算法实现>、<非递归算法实现>
- JAVA语言实现二叉树的层次遍历的非递归算法及递归算法。
- JAVA语言实现二叉树的层次遍历的非递归算法及递归算法
- 遍历二叉树的递归算法与非递归算法以及C语言实现
- 【LintCode-66】二叉树的前序遍历(Java实现-递归算法/非递归算法)
- 【LintCode-67】二叉树的中序遍历(Java实现-递归算法/非递归算法)
- 数据结构与算法学习记录--二叉树的创建,递归遍历,非递归遍历的实现
- C语言实现二叉树的常用的算法(递归与非递归实现遍历)
- 二叉树几种遍历算法的非递归实现
- 二叉树三种遍历算法递归和非递归实现
- Spring MVC--3.请求参数
- Maven简介
- 短路 移位运算符 小记equals
- taglib 自定义标签
- SDK和JDK区别
- 二叉树的遍历<递归算法实现>、<非递归算法实现>
- 油田问题(dfs)
- eclipse 导入c/c++ 源码
- sql on hadoop方案(5)
- ./startup.sh: /bin/sh^M: bad interpreter: 没有那个文件或目录 解决办法
- ZOJ - 3488 Conic Section
- 冒泡排序
- Android 关机实现
- 一边搭建一边理解MongoDB副本集(副本集读写语义)