怎樣去寫遞歸

    剛開始編程時,發現寫遞歸函數仍是有點難,搞很差就形成程序意外退出、卡死等尷尬處境。其實寫好遞歸函數只要把握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啦)。

相關文章
相關標籤/搜索