【数据结构】【二叉树后序遍历】【非递归实现方法】三种方法总结 浙江大学课程课后练习
2019-08-05 18:23
323 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012127385/article/details/98504638
非递归实现的先序与中序遍历、递归实现的三种二叉树遍历方法及结构定义将在后面给出)
后序遍历:左->右->根
方法一:取巧法
最优方法:将先序遍历的左右子顺序倒置后,逆序将输出结果。
即先序遍历为:根-左-右 左右子树顺序倒置后得到:根-右-左,逆序输出得到左-右-根。
使用两个栈储存,一个保存左右颠倒的先序遍历,一个保存结果,然后将结果逆序输出。
[code] void PostOrderTreaversalStack(BinTree BT) { //建立一个堆栈 TStack ts=CreateStack(); //保存结果用于逆序输出的堆栈 TStack tsR=CreateStack(); BinTree T=BT; while(T||!IsEmpty(ts))//栈和树指针全空时跳出循环 { while(T) { Push(ts,T); Push(tsR,T); T=T->Right; } if(!IsEmpty(ts)) { T=Pop(ts); T=T->Left; } } while(!IsEmpty(tsR)) { T=Pop(tsR); cout<<T->Date<<endl; } }
方法二:设置访问记录栈法
利用两个堆栈,一个正常使用的ts,一个存有存在右子树结点的tsR 。访问时,右子树非空时对比两个堆栈当前结点。结点相等便一起pop,不相等时右子树非空便push(tsR,ts指向的当前结点),T指针指向右子树。右子树空ts栈pop当前结点。
[code]void PostOrderTreaversalStack2(BinTree BT) { //建立一个正常的堆栈 TStack ts=CreateStack(); //保存右子树非空的结点,用于判断访问次数 TStack tsR=CreateStack(); BinTree T=BT; while(T||!IsEmpty(ts))//栈和树指针全空时跳出循环 { while(T) { Push(ts,T); T=T->Left; } if(!IsEmpty(ts)) { BinTree Tnow=(ts->Next)->TS;//主栈当前结点 BinTree TRnow=(tsR->Next)->TS;//访问栈当前结点 BinTree Tright=Tnow->Right;//获取结点右子树情况 if(!Tright)//右子树空 { T=Pop(ts); cout<<T->Date<<endl; T=T->Right;//相当于赋值为NULL } else if(Tright&&Tnow==TRnow) //右子树非空并且访问过刚好到那个结点 { T=Pop(ts); cout<<T->Date<<endl; T=Pop(tsR);//释放访问栈结点 T=NULL; //使循环进入下一个栈内结点 } else//右子树非空且未访问过 { Push(tsR,Tnow);//记录访问 T=Tright;//指向右子树 } } } while(!IsEmpty(tsR)) { T=Pop(tsR); cout<<T->Date<<endl; } }
方法三:在栈结构体中设置右子树访问次数的属性。根据访问次数判断是否pop(需要修改结构体,比较麻烦,不给出代码)
先序遍历与中序遍历:
[code]//中序遍历 //遇到一个结点就压栈,并去遍历该树的左子树; //当左子树遍历结束后,从栈顶弹出这个结点并访问它; //然后按其右指针再去遍历一遍该节点的右子树 //压入栈的是指针!!!! void InOrderTreversalStack(BinTree BT) { //建立一个堆栈 TStack ts=CreateStack(); BinTree T=BT; while(T||!IsEmpty(ts))//栈和树指针全空时跳出循环 { while(T) { Push(ts,T); T=T->Left; } if(!IsEmpty(ts)) { T=Pop(ts); cout<<T->Date<<endl; T=T->Right; } } } //先序遍历 void PreOrderTreaversalStack(BinTree BT) { //建立一个堆栈 TStack ts=CreateStack(); BinTree T=BT; while(T||!IsEmpty(ts))//栈和树指针全空时跳出循环 { while(T) { Push(ts,T); cout<<T->Date<<endl; T=T->Left; } if(!IsEmpty(ts)) { T=Pop(ts); T=T->Right; } } }
递归方法:
[code]//递归遍历 //先序遍历 根->左->右 void PreOrderTreaversal(BinTree BT) { if(BT)//不为空 { cout<<BT->Date<<endl; PreOrderTreaversal(BT->Left); PreOrderTreaversal(BT->Right); } } //中序遍历 左->根->右 void InOrderTreaversal(BinTree BT) { if(BT) { InOrderTreaversal(BT->Left); cout<<BT->Date<<endl; InOrderTreaversal(BT->Right); } } //后序遍历 左->右->根 void PostOrderTreaversal(BinTree BT) { if(BT) { PostOrderTreaversal(BT->Left); PostOrderTreaversal(BT->Right); cout<<BT->Date<<endl; } }
二叉树与堆栈定义:
[code]#define MAXSIZE 1024 //链表方式储存 二叉树 typedef int ElementType; typedef struct TreeNode *BinTree ; struct TreeNode { ElementType Date; BinTree Left; BinTree Right; }; //链表方式储存堆栈 typedef struct TreeStack *TStack; struct TreeStack{ BinTree TS;//储存指针 TStack Next;//指向下一个栈值 }; TStack CreateStack() //建立一个堆栈 { TStack head=(TStack)malloc(sizeof(TreeStack));//申请头结点 if(head){ head->Next=NULL;//TS不保存任何信息 } return head; } bool IsEmpty(TStack TS)//判断是否非空 true为空 false为非空 { return (TS->Next==NULL); } bool Push(TStack S,BinTree BT)//入栈 true成功入栈 { TStack ts =(TStack)malloc(sizeof(TreeStack));//申请新结点的空间 if(ts)//申请成功 { ts->TS=BT; ts->Next=S->Next; S->Next=ts; return true; } else return false; } BinTree Pop(TStack S)//出栈并释放空间 { if(S->Next)//判断S非空 { TStack ts; BinTree B; ts=S->Next; B=ts->TS; S->Next=ts->Next; free(ts); return B; } else return NULL; }
相关文章推荐
- 数据结构(二叉树系列)先序创建三种遍历和求深度(递归实现)
- C++实现二叉树前序中序后续遍历的非递归方法总结
- 数据结构练习(39)二叉树前中后序遍历的非递归实现
- 重温数据结构:二叉树的常见方法及三种遍历方式 Java 实现
- 用递归,迭代,通项公式三种方法实现斐波那契数列求解
- 重温数据结构:二叉树的常见方法及三种遍历方式 Java 实现
- 重温数据结构:二叉树的常见方法及三种遍历方式 Java 实现
- Java基础课程学习总结,使用LinkedList简单模拟队列数据结构和堆栈数据结构的实现
- php实现斐波那契数列的三种方法,递归回调和迭代器和数组之间性能对比
- 斐波拉契数列进行编译,采用三种不同的方法实现,迭代,递归,数组
- 简易JAVA爬虫练习,为新手总结的三种爬虫方法
- ASP.NET(c#)实现重定向的三种方法的总结
- 数据结构--树的三种遍历(递归与非递归实现)
- 用非递归方式实现二叉树的前、中、后三种遍历方法
- [数据结构]10.2实现binary search tree的查找和插入操作,用非递归的方法实现
- 总结以下三种方法,实现c#每隔一段时间执行代码:
- 数据结构用递归和非递归方法实现二分查找法
- 树(tree)结构表递归查询的实现方法总结
- ASP.NET(c#)实现重定向的三种方法的总结
- 数据结构(C#)--斐波那契数列的递归实现方法