一文搞明白java遍历循环递归深度优先广度优先的区别
Posted 隔壁老易
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一文搞明白java遍历循环递归深度优先广度优先的区别相关的知识,希望对你有一定的参考价值。
表设置
列名 | 类型 |
---|---|
id | varchar |
parentId | varchar |
其他字段 |
... |
使用循环与使用递归的区别是什么?
-
递归即是自己调用自己,凡是方法内的有调自己的都属于递归。
public void exampleMethod() {
exampleMethod() ;
}
-
循环不存在自己调用自己,循环可以嵌套。
public void exampleMethod() {
for(int i = 0 ; i < length ; i ++) {
for(int j =0 ; j < size; j ++) {
}
}
}
-
函数调用是有时间和空间消耗的,每一次函数调用,都需要再内存中分配空间以保存参数、返回地址及临时变量。而且往栈里压入数据和弹出数据都需要时间,更何况,每个进程的栈的容量是有限的。因此,递归实现的效率不如循环。 -
抛开业务、场景等因素,循环和递归是可以相互改写的。 但是一般情况下用递归要比循环的代码逻辑上好理解一些。
深度优先和广度优先
-
什么是深度优先?打个不恰当的比喻,吃面时,你总是一根根的吃,一根不吃完,你不会吃其他的。 -
什么是广度优先?还是吃面,你总一大口一大口的吃,但是一口吃到嘴巴,你咽不下去,只能咬断了,先咽了再吃另外一口。 -
编码实例
用递归实现深度优先
public List<ImageText> getListByParentId(String parentId) {
return this.imageTextDao.getListByParentId(parentId);
}
//递归
private void count(List<Long> statistics , List<ImageText> imageTextArray) {
for(ImageText imageText : imageTextArray) {
statistics.add(1L) ;
List<ImageText> tempChilds2 = this.imageTextService.getListByParentId(imageText.getId()) ;
if (CollectionUtils.isNotEmpty(tempChilds2)) {
this.count(statistics, tempChilds2);
}
}
}
//方法入口
public Long countRelayById(String id) {
List<Long> statistics = Lists.newArrayList() ;
List<ImageText> imageTextArray = this.imageTextService.getListByParentId(id) ;
this.count(statistics, imageTextArray) ;
return statistics.size() ;
}
用循环实现广度优先
public List<ImageText> getListByParentId(String parentId) {
return this.imageTextDao.getListByParentId(parentId);
}
//循环
public Long countRelayById(String id) {
Long statistics = 0l ;
List<ImageText> imageTextArray = this.imageTextService.getListByParentId(id) ;
while(CollectionUtils.isNotEmpty(imageTextArray)) {
List<ImageText> tempChilds = null ;
for (ImageText child : imageTextArray) { // 遍历子节点
// ------------
// 获取child内容,或其他处理
// ------------
statistics ++ ;
List<ImageText> tempChilds2 = this.imageTextService.getListByParentId(child.getId()) ;
if (CollectionUtils.isNotEmpty(tempChilds2)) {
if(tempChilds == null) {
tempChilds = Lists.newArrayList() ;
}
tempChilds.addAll(tempChilds2);
}
}
imageTextArray = tempChilds;
}
return statistics;
}
以上是关于一文搞明白java遍历循环递归深度优先广度优先的区别的主要内容,如果未能解决你的问题,请参考以下文章
树二叉树遍历算法(深度优先广度优先遍历,前序中序后序层次)及Java实现
数据结构与算法图遍历算法 ( 深度优先搜索 DFS | 深度优先搜索和广度优先搜索 | 深度优先搜索基本思想 | 深度优先搜索算法步骤 | 深度优先搜索理论示例 )