python时间复杂度和空间复杂度_文件递归算法的时间和空间复杂度

我的时间和空间分析对这种算法是否正确?

def find_files(suffix, path):

if suffix == '':

return []

# Base condition

if len(os.listdir(path)) == 0:

return []

path_elements = os.listdir(path)

path_files = [file for file in path_elements if ('.' + suffix) in file]

path_folders = [folder for folder in path_elements if '.' not in folder]

for folder in path_folders:

path_files.extend(find_files(suffix=suffix, path=path + '/' + folder))

return path_files

# Tests

path_base = os.getcwd() + '/testdir'

print(find_files(suffix='c', path=path_base))

说明:文件递归

需求:

目的是编写代码以查找目录下的所有文件(及其下所有目录),这些文件以“ .c”结尾

概要:

为了实现这一点,我使用了find_files将带有suffix(文件扩展名)和path(我们需要搜索的目录路径)的函数。在此功能中,我将在父目录及其所有子目录中递归搜索具有给定扩展名的文件。我将所有具有给定后缀的文件存储在列表中并返回。

时空复杂度:

时间复杂度:

os.listdir(path)将列出给定路径中的所有文件和文件夹。由于必须迭代每个项目才能提供列表,因此需要线性时间复杂度。设epath_elements的长度=>O(len(path_elements))=>O(e)

path_elements = os.listdir(path)

下面的行将通过检查.c文件名中是否存在来查找给定路径中的所有文件。如果s是字符串的长度(文件/文件夹的名称),则O(s)查找具有给定扩展名的文件需要花费时间。因此,f文件数量需要O(f*s)时间。出于这样的实际目的,可以公平地假设文件名不是无限长。因此,我们可以假定s为常数=>O(f * 1)=>O(f)。

path_files = [file for file in path_elements if ('.' + suffix) in file]

同样,遍历g目录将花费线性时间=>O(g)

path_folders = [folder for folder in path_elements if '.' not in folder]

以上3个步骤将采取=>O(e + f + g)=>O(e)。由于,e(len(path_elements))是一个主项,因为它是一个组合path_files和path_folders

对于递归,如果每个级别中k的目录数(branches),depth则递归将采用O(brancher^depth)=>O(k^depth)。但是,对于每个递归调用,都执行上述三个步骤。因此,总时间复杂度为O((k^depth) * e

空间复杂度:

输入空间

后缀-O(1)

路径-O(1)

路径元素+路径文件+路径文件夹=>O(e + f + g)=>O(e)

辅助空间

递归使用称为“调用栈”的东西。当一个函数调用自身时,该函数将进入堆栈的顶部。

在此算法中,仅当递归函数遍历每个目录时,它才被用尽。换句话说,到达时depth。因此O(depth),调用堆栈中需要空间。

总空间复杂度=>输入空间+辅助空间=>O(e + depth)

解决方案

我认为复杂度为O(path_elements),其中path_elements所有对的调用返回的文件和文件夹总数os.listdir()。考虑一个文件夹在一个目录中有四个文件:

folder

zip.c

foo.c

bar.c

bas.c

因此,您的函数调用os.listdir(),该函数返回四个文件。这样n = 4。然后,代码遍历列表以查找找不到文件夹的文件夹,然后再次选择.c文件并将其添加到列表中。

这里的复杂度是O(n)调用os.listdir(),O(n)搜索文件夹,以及O(n)选择.c文件并将它们添加到列表中。总共为O(3 * n),即O(n)。

现在考虑以下目录树:

folder

sub1

zip.c

foo.c

sub2

bar.c

bas.c

So the first call to find_files calls os.listdir(folder), which returns two folders. Each folder makes a recursive call to find_files. Altogether there are three calls to os.listdir(), and each one returns two files, so the total number of items returned by os.listdir() is 6.

Now imagine you had:

folder

sub0

sub1

sub2

sub3

...

sub30

file1.c

The complexity here is still O(n). In this case, n is 31.

The point I'm trying to make here is that you look at each item returned from os.listdir() a constant number of times. Thus, O(n).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值