二叉树的非递归先序、中序、后序遍历
来源:互联网 发布:linux exp continue 编辑:程序博客网 时间:2024/05/21 18:48
算法思想:
先序:NLR的访问顺序,由于R节点,即右孩子的访问需要通过根节点的指针来实现,所以,需要设一个栈来存储根节点。具体看代码:
void preorder(btree t){ initstack(s);//初始化栈 btree p=t; while(p||!empty(s)){ if(p){//如果该节点非空 visit(p);//访问 push(s,p);//入栈,栈中元素全部非空 p=p->lchild;//走到最左 } else{//空节点 pop(s,p);//退栈,栈中元素全部非空 p=p->lchild;//转向右子树 } }//while}
中序遍历和先序遍历几乎一样:
void midorder(btree t){ initstack(s); btree p=t; while(p||!empty(s)){ if(p){ push(s,p); p=p->lchild; } else{ pop(s,p); visit(p); p=p->rchild; } }}
后序遍历:LRN顺序。L和R都需要通过N的左右指针来指向,所以L和R未访问完之前,N都要放在栈内。具体为,从L返回时,N不能退栈,从R返回或R为空时,N退栈并访问。而要判断是从L返回还是后者,需要用一个指针r记录最近访问的节点来判断是从L还是R返回。
void postorder(btree t){ initstack(s); btree p=t,r=null;//r记录最近访问的节点,初始化为空 while(p||!empty(s)){ if(p){//走到最左 push(s,p); p=p->lchild; } else{//p为空 gettop(s,p);//先获取栈顶,而不是退栈 if(p->rchild&&p->rchild!=r){//右孩子存在且未被访问过 //转向右子树并再走向左孩子 p=p->rchild; push(s,p); p=p->lchild; } else{//没有右孩子或者右孩子被访问过(从右边返回) //退栈并访问该根节点 pop(s,p); visit(p); r=p;//用r记录最近访问的节点 p=null;//p置空,以防再次入栈 }//else }//else }//while}
后序遍历的应用:找祖先,栈顶元素以下的元素全部为其祖先。具体为,把visit部分改为:依次输出栈内元素。
若找x、y的共同祖先,假设x在y的左边,则必然先遍历到x,此时先把栈内元素复制到另一个辅助栈(x的祖先),继续遍历到y时,依次退栈并和辅助栈中的元素比较,若遇到相等的则为共同祖先。
btree conancestor(btree t,btnode *x,btnode *y){//查找x,y的共同祖先并返回 initstack(s); initstack(s1);//辅助栈 btree p=t,r=null; while(p||!empty(s)){ if(p){ push(s,p); p=p->lchild; } else{ gettop(s,p); if(p->rchild&&p->rchild!=r){ p=p->rchild; push(s,p); p=p->lchild; } else{ pop(s,p); if(p==x) stack s1=s;//将s栈中元素复制到辅助栈s1 if(p==y){ i=s1.top; while(p!=s1.data[i]&&i>-1) i--; if(p==s1.data[i] return p;//找到共同祖先,返回p pop(s,p);//没有找到,继续退栈 }//if(p==y) r=p; p=null; }//else }//else }//while}
阅读全文
1 0
- 二叉树的先序、中序、后序递归遍历和非递归遍历
- 二叉树的先序、中序、后序遍历的递归和非递归实现
- 二叉树的后序,先序,中序遍历的非递归遍历
- 二叉树的先序、中序、后序、层序递归及非递归遍历
- 二叉树的先序/中序/后序(递归、非递归)+层序遍历
- 二叉树的遍历 中序 后序 先序 递归 非递归
- 二叉树的创建和先序,中序,后序,递归,非递归遍历
- 二叉树的遍历 先序 中序 后序 递归非递归
- 二叉树的先序、中序、后序遍历(递归 and 非递归)
- 二叉树 非递归 先序遍历 中序遍历 后序遍历 层次遍历
- 二叉树的先序遍历、中序遍历以及后序遍历(递归以及非递归方式)
- 二叉树的先序,中序,后序遍历的非递归算法
- 二叉树的先序,中序和后序遍历的非递归算法
- 二叉树的先序,中序,后序遍历的非递归算法
- 二叉树的先序、中序、后序遍历的非递归实现
- 二叉树的先序,中序,后序及其非递归遍历的方法
- 二叉树的遍历(2)--先序遍历,中序遍历,后序遍历(非递归)
- 二叉树的非递归遍历(先序,中序,后序)
- lua关键字
- mybatis批量插入写法
- 子查询,分页查询
- How to Install Grub Customizer in Ubuntu 16.04 LTS
- python学习之路--内存管理
- 二叉树的非递归先序、中序、后序遍历
- NoSQL 简单介绍
- update去空处理
- Spring学习笔记——事务
- insert主键冲突控制
- Redis入门到精通-Redis与Java的应用
- 前段请求跨域的原理及实践
- MyBatis之优化配置文件
- return/exit/—exit三种返回方式的区别