【算法题】二叉树的前序遍历(递归和非递归算法分析)
来源:互联网 发布:java上传图片到tomcat 编辑:程序博客网 时间:2024/05/18 06:24
问题:对二叉树的前序遍历(递归和非递归算法)
递归算法:输出根节点的值
对左子树进行左遍历
对右子树进行遍历
代码如下:
这个算法的执行时间是多少呢?因为每个节点被检查了一次,所以它是O(n)级的。
非递归算法:要完成该算法,需要深入分析一下递归算法的本质,再用循环算法来模拟它的动作。递归算法使用了堆栈这种数据结构,利用堆栈来完成数据处理。
堆栈的四个函数:
int Push(element **stack,void *data);
int Pop(element **stact,void **data);
int CreateStack(element **stack);
int deleteStack(element **stack);
首先来探究下递归算法的本质:
递归算法:a.输出根节点的值
b.对左子树进行左遍历
c.对右子树进行遍历
第一次进入递归函数的时候,先输出根节点的值,然后递归地调用这个函数对左子树进行遍历。在发出这个递归调用的时候,调用者的程序状态就会被压入堆栈保存起来,这样在递归调用返回时,调用者就能从自己离开的地方开始继续执行。
对左遍历算法来说,调用者将继续对右子树进行左遍历。为了能在遍历完左子树之后开始对右子树的遍历,递归调用隐含地把右子树的地址保存在堆栈上。在输出一个节点之后但在前进到它的左节点之前,该节点的右节点将被压入一个你不知道的堆栈里保存起来。当没有子节点可供处理时,就会从递归调用中返回一层,从堆栈上弹出一个右节点,然后以它为起点继续进行左遍历。
总结:这个算法先输出当前节点的值,然后再把它的右节点压入堆栈,然后前进到它的左节点;当没有子节点可供处理时,算法将从堆栈上弹出一个新的当前节点。这个过程将一直重复到遍历完所有的节点为止,堆栈里也不再有任何数据。
注:必须保证左节点总是先于右节点被弹出来,所以得先压入右节点,再压入左节点。
非递归算法如下:
创建堆栈
把根节点压入堆栈
当堆栈不为空,循环
弹出一个节点
如果这个节点不是NULL
输出它的值
把这个节点的右节点压入堆栈
把这个节点的左节点压入堆栈
代码如下:
这个算法的时间开销也是O(n)
递归算法:输出根节点的值
对左子树进行左遍历
对右子树进行遍历
代码如下:
void PreorderTraversal(node *root){ if(root) printf("%d\n",root->value);elsereturn ;PreorderTraversal(root->left);PreorderTraversal(root->right);}
这个算法的执行时间是多少呢?因为每个节点被检查了一次,所以它是O(n)级的。
非递归算法:要完成该算法,需要深入分析一下递归算法的本质,再用循环算法来模拟它的动作。递归算法使用了堆栈这种数据结构,利用堆栈来完成数据处理。
堆栈的四个函数:
int Push(element **stack,void *data);
int Pop(element **stact,void **data);
int CreateStack(element **stack);
int deleteStack(element **stack);
首先来探究下递归算法的本质:
递归算法:a.输出根节点的值
b.对左子树进行左遍历
c.对右子树进行遍历
第一次进入递归函数的时候,先输出根节点的值,然后递归地调用这个函数对左子树进行遍历。在发出这个递归调用的时候,调用者的程序状态就会被压入堆栈保存起来,这样在递归调用返回时,调用者就能从自己离开的地方开始继续执行。
对左遍历算法来说,调用者将继续对右子树进行左遍历。为了能在遍历完左子树之后开始对右子树的遍历,递归调用隐含地把右子树的地址保存在堆栈上。在输出一个节点之后但在前进到它的左节点之前,该节点的右节点将被压入一个你不知道的堆栈里保存起来。当没有子节点可供处理时,就会从递归调用中返回一层,从堆栈上弹出一个右节点,然后以它为起点继续进行左遍历。
总结:这个算法先输出当前节点的值,然后再把它的右节点压入堆栈,然后前进到它的左节点;当没有子节点可供处理时,算法将从堆栈上弹出一个新的当前节点。这个过程将一直重复到遍历完所有的节点为止,堆栈里也不再有任何数据。
注:必须保证左节点总是先于右节点被弹出来,所以得先压入右节点,再压入左节点。
非递归算法如下:
创建堆栈
把根节点压入堆栈
当堆栈不为空,循环
弹出一个节点
如果这个节点不是NULL
输出它的值
把这个节点的右节点压入堆栈
把这个节点的左节点压入堆栈
代码如下:
void PreorderTraversal(node *root){element *theStack;void *data;node *curNode;CreateStack(&theStack);Push(&theStack,root);while(Pop(&theStack,&data)){curNode=(node *)data;if(curNode){printf("%d\n",curNode->value);Push(&theStack,curNode->right);Push(&theStack,curNode->left);}}DeleteStack(&theStack);}
这个算法的时间开销也是O(n)
- 【算法题】二叉树的前序遍历(递归和非递归算法分析)
- [算法]二叉树的非递归前序遍历算法
- 算法习题43:递归和非递归实现二叉树的前序遍历
- 二叉树的前序遍历、中序遍历和后序遍历的递归和非递归算法
- 【LintCode-66】二叉树的前序遍历(Java实现-递归算法/非递归算法)
- 二叉树的递归和非递归的遍历算法
- 【二叉树】非递归遍历的通用算法:前序、中序和后序
- 遍历二叉树的递归和非递归算法
- 二叉树遍历的递归和非递归算法
- 二叉树的遍历-递归和非递归算法
- 二叉树的递归和非递归遍历算法
- 二叉树的遍历算法(递归和非递归)
- 二叉树的遍历(前 中 后序 )递归 非递归算法
- (前、中、后)序遍历二叉树的递归、非递归算法!
- 【二叉树遍历算法】——前/中/后序递归与非递归的实现
- 【数据结构】二叉树(前、中、后)序遍历的递归与非递归算法
- 二叉树的前序、中序、后序遍历的算法(递归形式和非递归形式)
- 二叉树的遍历(前序,中序,后序,层序)--递归和非递归算法实现
- java中关于replaceAll和appendReplacement的笔记
- 正则表达式标志
- nginx访问php页面出现No input file specified.
- 开启apache的url rewrite模块
- p,&p,*p的区别
- 【算法题】二叉树的前序遍历(递归和非递归算法分析)
- jquery图片滚动效果插件SuperSlide1.2
- 如何更改struts中错误默认返回input InputConfig内methodName跟resultName的使用方法
- javaEE--ibatis--Sping+flex4 调用存储过程返回List结果集
- 监听输入框值的即时变化onpropertychange、oninput
- AudioManager学习
- 日语的商品购物与消费
- ABAddressBook & AddressBook UI 文件介绍(IOS开发)
- VC内存泄露检测之运行时库(CRT)