python 遞迴(附利用棧和佇列模擬遞迴)

2022-08-03 00:09:17 字數 4069 閱讀 8163

凡是迴圈能幹的事,遞迴都能幹12

34方法:

1、寫出臨界條件

2、找這一次和上一次的關係

3、假設當前函式已經能用,呼叫自身計算上一次的結果再求出本次的結果

下面我們通過兩段**簡單看一下遞迴和非遞迴的區別:

輸入乙個大於等於1的數,求1到n的和!

1 # 普通函式方法

2 3 def hanshu(n):

4 sum = 0

5 # 迴圈遍歷每乙個數字,將他們加到乙個事先定義好的變數上,直到加完

6 for x in range(1, n+1):

7 sum += x

8 return sum

下面看一下通過遞迴的方法:

1 # 遞迴

2 3 def digui(n):

4 if n == 1:

5 return 1 # 如果n等於1證明已經遞迴到最後,返回1,這就是上述的臨界條件

6 else:

7 return n + digui(n-1) # 當沒有達到臨界條件時,用n加上對n-1的遞迴,每次都把n加進去,但是後面依然是使用當下這個遞迴函式,會再次呼叫計算n-1,直到遞迴結束,也就是將從n到1的數全部遞迴完

在實際應用中,遞迴是十分消耗記憶體的,但是有些事情他很容易去做,很容易理解。下面,就通過乙個案例介紹一下遞迴的用法。

1 import os # 由於我們遍歷目錄,所以要找到那個目錄並操作,os模組包含普遍的作業系統功能

2 3 path = "" # 這是我們要遍歷的目錄的路徑,需要自己寫進去

4 5 # 既然是遞迴函式,那麼肯定要有個函式,而且這個函式還將在函式內部再次被呼叫

6 def getalldir(path, sp = ''): # 引數中傳入路徑和sp,這個我最後說一句你就明白了

7 # 得到當前目錄下的所有檔案

8 fileslist = os.listdir(path) # os.listdir()是os模組下的乙個方法,相當於linux中的ls,檢視所有檔案

9 10 sp += " " # 這個也先放一下

11 # 處理每乙個檔案

12 for filename in fileslist: # 遍歷剛才找到的目錄下的所有檔案

13 # 判斷是否是目錄(要用絕對路徑)

14 fileabspath = os.path.join(path,filename) # join是os模組下將兩個路徑拼接在一起的意思,第二個引數不能有斜槓。因為我們要判斷一下這個檔案是乙個普通檔案還是乙個目錄,所有要先把他的絕對路徑整理出來

15 if os.path.isdir(fileabspath): # isdir是判斷是否為目錄,是則返回true

16 print(sp + "目錄:", filename) # 列印當前這個檔案,他是個目錄

17 getalldir(fileabspath,sp = " ") # 這裡就開始遞迴了,因為我們要找到整個目錄裡的東西,所以當這個檔案還是個目錄的時候我們需要繼續向下找

18 else:

19 print(sp + "普通檔案:", filename) # 如果僅僅是個普通檔案,那麼他裡面也就沒有其他檔案了,就可以直接列印他了

20 21

22 getalldir(path) # 這裡是呼叫函式,讓遍歷開始

23 24 # 最後我來說一下開始寫的那個sp,是space的意思,有人也許現在就明白了。那個其實就是讓我們方便觀察,因為每次列印都是頂行寫的,我們分不清他的目錄結構,所以通過空格來調整。在函式內部寫乙個空格增加的表示式,可以使呼叫次數和空格數相關起來,遞迴的越深,證明目錄的級越低,那麼空格越多

1 # 整體思路是沒有變得,這裡沒有寫到的也許是重複的,看下上面注釋就好了

2 # 寫了一半想起來應該回來寫一下棧:棧就是乙個容器,但它只有乙個口,入棧出棧都從這乙個口,而且這個棧很細,進去了就不能顛倒位置了,所以,每入棧乙個元素他在最外面時候可以出來,否則得等前面的走完了它才可以出來

3 import os

4 5 def getalldirdfs(path):

6 stack = # 這裡是用棧來模擬,我們先建立乙個列表當做棧

8 9 # 處理棧,當棧為空時結束迴圈(棧為空就說明棧裡沒有普通檔案和目錄了,因為我們是每操作乙個要把那個取出來)

10 while len(stack) != 0:

11 # 從棧中取出資料

12 dirpath = stack.pop() # pop函式是刪除最後乙個元素,同時還有乙個返回值,就是去除的那個元素,我們再接收一下等等用

13 # 目錄下所有檔案

14 fileslist = os.listdir(dirpath) # 這個和上面一樣

15 16 # 處理每乙個檔案,如果是普通檔案則列印出來,如果是目錄則將該目錄位址壓棧

17 for filename in fileslist:

18 # print(dirpath)

19 fileabspath = os.path.join(dirpath,filename)

20 # print(fileabspath)

21 if os.path.isdir(fileabspath):

22 # 是目錄就壓棧

23 print("目錄:" + filename)

25 else:

26 # 列印普通檔案

27 print("普通:" + filename)

28 29 getalldirdfs(path)

1 # 這回記住了,先說一下佇列,隊是乙個兩端開口的模型,一頭進一頭出,當然還有雙向佇列,迴圈等等,我們就簡單用一下最基本的佇列

2 4 def getalldirbfs(path):

5 queue = collections.deque() # 建立乙個佇列,只要記得後面用法就是上面我說的那個不同就可以了

7 8 while len(queue) != 0:

9 dirpath = queue.popleft() # 僅僅這裡不同,因為佇列模擬是另一端出隊

10 fileslist = os.listdir(dirpath)

11 for filename in fileslist:

12 fileabspath = os.path.join(dirpath,filename)

13 if os.path.isdir(fileabspath):

14 print('目錄:' + filename)

16 else:

17 print('檔案:' + filename)

18 19 getalldirbfs(path)

20 21 # 大家想一下,棧是**進**出,也就是,剛進去的元素,接下來的一次迴圈又出來了,那便是一條路走到頭,是深度遍歷;那麼現在一頭進另一頭出是什麼

意思呢,就是即便判斷了這個是乙個目錄,但我現在不執行你,我要把你前面這些都查一遍,找完是目錄的都新增在後面,之後再遍歷你們這些,就是把一層的內容找完

再找下一層,被稱為廣度優先遍歷。

遞迴 棧和佇列遍歷

import os def getalldir path,sp fileslist os.listdir path 得到當前目錄下所有的檔案 sp for filename in fileslist 處理每乙個檔案 fileabspath os.path.join path,filename if ...

python學習筆記16(遞迴 棧和佇列)

遞迴呼叫 乙個函式,呼叫了自身,稱為遞迴呼叫 遞迴函式 乙個會呼叫自身的函式稱為遞迴函式 特點 凡是迴圈能幹的事,遞迴都能幹 過程 1 寫出臨界條件 2 找這一次和上一次的關係 3 假設當前函式已經能用,呼叫自身計算上一次的結果,再求出本次的結果 輸入乙個數 大於等於1 求1 2 3 n的和 用fo...

棧 佇列 遞迴

用陣列實現乙個順序棧class stack def init self self.items defisempty self return self.items defpush self,item def pop self return self.items.pop def peek self re...