刚开始编程时,发现写递归函数仍是有点难,搞很差就形成程序意外退出、卡死等尴尬处境。其实写好递归函数只要把握2点,就能够作到妈妈不再用担忧个人递归了。web
一、递归函数中要有调用本身的地方(也就是说有继续递归的条件和递归处理)编程
二、递归函数中要有结束本身的地方(也就是说有递归结束的条件和结束处理)函数
打印指定目录的文件结构(即有子目录,也要打印子目录下的文件)spa
打印的目录格式以下:code
--- home ------ MS --------- Version ------------ S900 --------------- odbg.jpg ------------ S910 --------------- myweb.jpg ------ VER --------- hello.txt
Go语言代码以下:递归
package main import ( "fmt" "io/ioutil" "os" ) func main() { var path string path = "G:\\home" err := PrintFilesInDir(path, "") if err != nil { fmt.Println("PrintFilesInDir:: err=", err.Error()) } } func PrintFilesInDir(dirPath string, preSpace string) error { //文件名前面空格,便于标识文件层次 preSpace = fmt.Sprintf("%s---", preSpace) //获取文件信息 finf, err := os.Stat(dirPath) if err != nil { fmt.Println("PrintFilesInDir:: os.Stat err=", err.Error()) return err } if finf.IsDir() { //若是是目录须要递归子文件 //打印目录名 fmt.Println(preSpace, "", finf.Name()) //获取此目录子文件名 finfs, err := ioutil.ReadDir(dirPath) if err != nil { fmt.Println("PrintFilesInDir:: ioutil.ReadDir err=", err.Error()) return err } for _, v := range finfs { sonDir := fmt.Sprintf("%s\\%s", dirPath, v.Name()) PrintFilesInDir(sonDir, preSpace) } } else { //若是不是目录,打印出此文件名,结束递归 fmt.Println(preSpace, "", finf.Name()) return nil } return nil }
到此为止,主要内容就已经说完了,下面就是一些关于递归的讨论了......string
(1)能够减小代码量。几行问题能够解决的不必使用几十行来写
(2)处理逻辑清晰,便于理解io
(1) 子问题须与原始问题为一样的事,且更为简单;class
(2)不能无限制地调用自己,须有个出口,化简为非递归情况处理。效率
其实就是一个问题中的一样的处理逻辑须要作不少次,并且处理逻辑中也有结束的处理。
运行效率较低、 在递归调用的过程中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易形成栈溢出等
本文主要给你们介绍,怎么去写递归,不会形成程序异常(只要把握住继续递归和结束递归条件这两点就OK啦)。