递归与循环写法互转
1:递归与循环理论上可以互转
2:递归顺序必须由父–>子 -->兄弟;
3:循环用压栈方式可以实现由父–>子 -->兄弟;用连表方式可以实现父–>兄弟—>子的顺序;
递归通用模板
/**
* 递归通用函数
*/
function dg($pms){
//符合某条件直接返回
if ($pms=='xxx'){
return 'xxx';
}
//根据参数获取数据
$datas=getDatas($pms);
if ($datas=="xxx"){
$data= $this->dg($datas['pms']);//根据参数再次调用
//TODO 处理数据
dealData($data);
}else{
//TODO 处理数据
dealData($datas);
}
}
递归转成循环通用模板
/**
* 递归--->转循环
*/
function xh($pms){
//定义一个栈保存任务(换成连表则顺序改为先找兄弟后找子)
$task=[];
//获取首次数据
$datas=getDatas($pms);
//将数据压入栈内
$task.push($datas);
//循环取栈
while ($task.length>0){
$data=$task.pop();//从栈中取出一个数据
//根据条件判断处理数据
if($data=='xxx'){
$datas=getDatas($data['pms']);//继续取数据,压到栈中
$task.push($datas);
}else{
//TODO 处理数据
dealData($data);
}
}
}
实例: 使用 递归 跟 循环 查找文件夹内的所有文件
递归写法(伪代码)
/**
* 递归找文件
*/
function getFilesDg($filename){
//文件直接返回
if (is_file($filename)){
return $filename;
}
//获得当前文件内的所有文件及文件夹
$list=getFiles($filename);
foreach ($list as $item) {
//判断是否文件夹
if (is_dir($item)){
$this->getFilesDg($item);//递归调用查找该文件夹里的文件
}else{
//输出文件名
echo "找到文件 $item";
}
}
}
循环找文件写法(伪代码)
/**
* 递归--->转循环 查找文件
*/
function getFilesXh($filename){
//定义一个栈保存任务(换成连表则顺序改为先找兄弟文件)
$task=[];
//获取该文件夹内的文件
$list=getFileList($filename);
//将数据压入栈内
$task.push($list);
//循环取栈
while ($task.length>0){
$data=$task.pop();//从栈中取出一个数据
foreach ($data as $item) {
//判断是文件夹
if(is_dir($item)){
$list=getFileList($item);//继续取数据,压到栈中
$task.push($list);
}else{
echo "找到文件 $item";
}
}
}
}
结论:循环更好用,逻辑更清晰,可以控制遍历顺序