- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我一直在写一些python脚本来测试和计时各种常见的算法,纯粹是为了自己的熏陶。我敢肯定已经有资源可以做到这一点,但我发现自己编写它们很有帮助。
我编写了一个实现冒泡排序、选择排序和插入排序的脚本,并且针对每个脚本运行 10 次不同数组大小的迭代,以及最佳/最差/平均数组顺序情况。
在大多数情况下,我看到了我所期望的结果,例如选择排序总是花费相同的时间,而不管数组的顺序如何,而冒泡排序的表现却如预期的那样糟糕。我还看到插入排序的性能确实随着给定数组顺序的提高而提高,但是我对选择和插入的比较感到困惑。
我知道这两种算法的最坏情况时间复杂度都是 O(n^2),而且插入排序的平均时间复杂度优于选择排序,但我发现在很多情况下,插入排序的性能比选择排序差,这对我来说似乎是不正确的。我希望两者在最坏的情况下表现相同,而插入排序在不是最坏的情况下表现会更好。我是不是误解了如何解释这些结果,还是我在执行这两种算法时犯了错误?
这是我的脚本:
import random
import time
import sys
from enum import Enum
class Case(Enum):
BEST = 1
WORST = 2
AVERAGE = 3
def bubble_sort(arr):
sorted = False
while not sorted:
sorted = True
for i in range(0, len(arr)):
# n
if i + 1 < len(arr) and arr[i] > arr[i + 1]:
scratch = arr[i]
arr[i] = arr[i + 1]
arr[i + 1] = scratch
sorted = False
return arr
def selection_sort(arr):
for i in range(0, len(arr)):
# n
min_index = i
for j in range(i + 1, len(arr)):
# n
if arr[j] < arr[min_index]:
min_index = j
scratch = arr[i]
arr[i] = arr[min_index]
arr[min_index] = scratch
return arr
def insertion_sort(arr):
for i in range(1, len(arr)):
# n
index = i
while index > 0 and arr[index - 1] > arr[index]:
# worst case n, best case 1
scratch = arr[index]
arr[index] = arr[index - 1]
arr[index - 1] = scratch
index -= 1
return arr
TOTAL_RUNS = 10
def verify(algorithm, name):
# first let's test that it actually sorts correctly
arr = list(range(1, 20))
random.shuffle(arr)
arr = algorithm(arr)
for i in range(0, len(arr) - 1):
if arr[i] > arr[i + 1]:
raise Exception("NOT SORTED!")
print("timing " + name + " sort...")
def time_the_algorithm(algorithm, case):
total = 0
min = sys.maxsize
max = 0
sizes = [1000,5000,10000]
for size in sizes:
for i in range(0, TOTAL_RUNS):
arr = list(range(1, size))
if case == Case.WORST:
# for worst case, reverse entire array
arr = list(reversed(arr))
elif case == Case.AVERAGE:
# average case, random order
random.shuffle(arr)
start = time.time()
arr = algorithm(arr)
end = time.time()
elapsed = end - start
total += elapsed
if elapsed > max:
max = elapsed
if elapsed <= min:
min = elapsed
print(name + ", n={0:} - ".format(size) + str(case) + ": avg {0:.2f}s, min {1:.2f}s, max {2:.2f}s".format(total/TOTAL_RUNS, min, max))
# worst case
time_the_algorithm(algorithm, Case.WORST)
# avg case
time_the_algorithm(algorithm, Case.AVERAGE)
# best case
time_the_algorithm(algorithm, Case.BEST)
verify(insertion_sort, "insertion")
verify(selection_sort, "selection")
verify(bubble_sort, "bubble")
这是我的输出:
timing insertion sort...
insertion, n=1000 - Case.WORST: avg 0.06s, min 0.06s, max 0.06s
insertion, n=5000 - Case.WORST: avg 1.42s, min 0.06s, max 1.46s
insertion, n=10000 - Case.WORST: avg 6.90s, min 0.06s, max 5.70s
insertion, n=1000 - Case.AVERAGE: avg 0.03s, min 0.03s, max 0.03s
insertion, n=5000 - Case.AVERAGE: avg 0.71s, min 0.03s, max 0.70s
insertion, n=10000 - Case.AVERAGE: avg 3.44s, min 0.03s, max 2.76s
insertion, n=1000 - Case.BEST: avg 0.00s, min 0.00s, max 0.00s
insertion, n=5000 - Case.BEST: avg 0.00s, min 0.00s, max 0.00s
insertion, n=10000 - Case.BEST: avg 0.00s, min 0.00s, max 0.00s
timing selection sort...
selection, n=1000 - Case.WORST: avg 0.02s, min 0.02s, max 0.02s
selection, n=5000 - Case.WORST: avg 0.43s, min 0.02s, max 0.43s
selection, n=10000 - Case.WORST: avg 2.17s, min 0.02s, max 1.84s
selection, n=1000 - Case.AVERAGE: avg 0.01s, min 0.01s, max 0.02s
selection, n=5000 - Case.AVERAGE: avg 0.43s, min 0.01s, max 0.44s
selection, n=10000 - Case.AVERAGE: avg 2.30s, min 0.01s, max 1.93s
selection, n=1000 - Case.BEST: avg 0.01s, min 0.01s, max 0.02s
selection, n=5000 - Case.BEST: avg 0.42s, min 0.01s, max 0.41s
selection, n=10000 - Case.BEST: avg 2.26s, min 0.01s, max 1.92s
timing bubble sort...
bubble, n=1000 - Case.WORST: avg 0.11s, min 0.11s, max 0.11s
bubble, n=5000 - Case.WORST: avg 3.15s, min 0.11s, max 3.24s
bubble, n=10000 - Case.WORST: avg 15.09s, min 0.11s, max 13.66s
bubble, n=1000 - Case.AVERAGE: avg 0.09s, min 0.09s, max 0.10s
bubble, n=5000 - Case.AVERAGE: avg 2.62s, min 0.09s, max 2.63s
bubble, n=10000 - Case.AVERAGE: avg 12.53s, min 0.09s, max 10.90s
bubble, n=1000 - Case.BEST: avg 0.00s, min 0.00s, max 0.00s
bubble, n=5000 - Case.BEST: avg 0.00s, min 0.00s, max 0.00s
bubble, n=10000 - Case.BEST: avg 0.00s, min 0.00s, max 0.00s
编辑:
我听取了@asaf-rosemarin 的建议,并尝试用 for 循环替换 while 循环,看看这是否会使时间更均匀,但它似乎根本不会影响性能
def insertion_sort(arr):
for i in range(1, len(arr)):
# n
for j in range(i, 0, -1):
# worst case n, best case 1
if arr[j - 1] > arr[j]:
scratch = arr[j]
arr[j] = arr[j - 1]
arr[j - 1] = scratch
else:
break
return arr
输出:
timing insertion sort...
insertion, n=1000 - Case.AVERAGE: avg 0.03s, min 0.03s, max 0.03s
insertion, n=5000 - Case.AVERAGE: avg 0.72s, min 0.03s, max 0.74s
insertion, n=10000 - Case.AVERAGE: avg 3.61s, min 0.03s, max 3.13s
timing selection sort...
selection, n=1000 - Case.AVERAGE: avg 0.02s, min 0.02s, max 0.02s
selection, n=5000 - Case.AVERAGE: avg 0.47s, min 0.02s, max 0.51s
selection, n=10000 - Case.AVERAGE: avg 2.52s, min 0.02s, max 2.17s
timing bubble sort...
bubble, n=1000 - Case.AVERAGE: avg 0.10s, min 0.09s, max 0.10s
bubble, n=5000 - Case.AVERAGE: avg 2.56s, min 0.09s, max 2.50s
bubble, n=10000 - Case.AVERAGE: avg 12.31s, min 0.09s, max 10.34s
最佳答案
你对时间复杂度的理解是正确的,我在你的实现中没有发现任何错误,所以我猜测原因是for ... in range
比 while
快在 python 中循环。
(更多信息在这里Why is looping over range() in Python faster than using a while loop?)
编辑:
时间复杂度之间的比较与实现的实际运行时间之间的比较之间存在这种不一致的原因是时间复杂度只考虑比较的数量,而忽略了额外的操作开销(因为它是 O(1)
对于每个比较),但那些额外的操作及其实现方式(例如编译与解释、缓存友好性)可能会显着影响运行时间。
关于python - 插入排序实现不正确,还是时间复杂度理解不正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54620346/
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!