摘要
本报告介绍了了遍历查找和二分查找两种算法,并用 python 语言将其实现。通过对要查找的数组的大小的变化控制,用 matplotlib 库函数绘制出了两种算法分别的时间复杂度的图像,并进行数据分析和比较。
关键词: 遍历查找;二分查找;时间复杂度
1. 引言
遍历查找是通过从头到尾遍历一个数组,查找数组中是否有所要查找的数。
二分查找是在一个有序的数组中,把要查找的数和数组最中间位置的数比较,按照这种逻辑在数组中找到要查找的数字。
通过描述可知二分查找的效率是要比遍历查找高的,下面的实验通过时间复杂度图表的绘制来证明了二分查找算法的相对高效。并且得出了两种算法分别的 BigO,遍历查找的时间复杂度是O(n), 而二分查找的时间复杂度是 O(logn)。
2. 遍历查找
2.1 算法阐述
- 在遍历查找中,依次生成一组随机数,存放在数组中,数组的大小分别是1000, 10000,100000,1000000,10000000。
随机数生成的 k 即为需要在数组中找的数字。 - 随后,用 for 循环遍历数组,并与 k 依次比较,直到找到 k 为止。
- 为了实验的准确性,需要将代码重复跑十次,并记录下时间的平均值。
2.2 实验代码
import time
import random
import matplotlib . pyplot as plt
import numpy as np
1
# 生 成 随 机 数 组
def random _ int _ list ( start , stop , length ) :
start , stop = ( int ( start ) , int ( stop ) ) if start <= stop else ( int ( stop ) , int (
start ) )
length = int ( abs ( length ) ) if length else 0
random _ list = []
for i in range ( length ) :
random _ list . append ( random . randint ( start , stop ) )
random _ list . sort ()
return random _ list
# 遍 历 数 组 找 k
def traverse _ Search (a , k ) :
found = False
time _ start = time . time ()
for index in range ( len ( a ) ) :
if k == a [ index ]:
found = True
time _ end = time . time ()
total _ time = time _ end - time _ start
return total _ time
if __ name __ == "__ main __":
x = [1000 , 10000 ,100000 ,1000000 ,10000000]
time _ list = []
for index in range ( len ( x ) ) :
average _ time = []
randomlist = random _ int _ list (1 , 100 , x [ index ])
for i in range (10) :
# print ( ’ x : ’ , x [ index ])
randomnumber = random . randint (1 ,100)
# print ( randomnumber )
average _ time . append ( traverse _ Search ( randomlist , randomnumber ) )
# 求 平 均 值
average = np . mean ( average _ time )
print ( average )
time _ list . append ( average )
# 用 matplotlib 画 图
plt . figure ()
plt . plot (x , time _ list , marker = ’* ’ , label = " binary search ")
plt . show ()
2.3 实验结果
实验数据:
x:1000 y:7.131099700927735e05
x:10000 y:0.000899505615234375
x:100000 y:0.0076825618743896484
x:10000000 y:0.8319803237915039
由实验可知,遍历查找的时间复杂度为 O(n), 随着自变量的增大线性增长。
3. 二分查找
3.1 算法阐述
- 在二分查找中,每次生成一组有序的随机数组,数组的大小分别是1000, 10000,100000,1000000,10000000。
- 在算法最开始时,将数组最左边和最右边作为界限,取最中间的数,并与随机生成的 k(要找的数字)进行比较。当 k 比中间的数字小时,则把最右边的界限改成中间的位置前一位的地方。当 k 比中间的数字大时,则把最左边的界限改成中间位置后一位的地方,以此类推查找,直到找到想要找的数字为止。
- 为了实验的准确性,需要将代码重复跑十次,并记录下时间的平均值。
3.2 实验代码
import time
import random
import matplotlib . pyplot as plt
import numpy as np
# 生 成 随 机 数 组
def random _ int _ list ( start , stop , length ) :
start , stop = ( int ( start ) , int ( stop ) ) if start <= stop else ( int ( stop ) , int (
start ) )
length = int ( abs ( length ) ) if length else 0
random _ list = []
for i in range ( length ) :
random _ list . append ( random . randint ( start , stop ) )
random _ list . sort ()
return random _ list
# 二 分 查 找 算 法
def binary _ search (A , k ) :
first = 0
last = len ( A ) -1
found = False
time _ start = time . time ()
while first <= last and not found :
midpoint = ( first + last ) //2
if A [ midpoint ] == k :
found = True
else :
if k < A [ midpoint ]:
last = midpoint -1
else :
first = midpoint +1
time _ end = time . time ()
total _ time = time _ end - time _ start
# print ( ’ totally cost ’ , total _ time )
return total _ time
if __ name __ == "__ main __":
x = [1000 , 10000 ,100000 ,1000000 ,10000000]
time _ list = []
for index in range ( len ( x ) ) :
average _ time = []
for i in range (10) :
# print ( ’ x : ’ , x [ index ])
randomlist = random _ int _ list (1 , x[ index ] , x [ index ])
randomnumber = random . randint (1 , x [ index ])
4
# print ( randomnumber )
average _ time . append ( binary _ search ( randomlist , randomnumber ) )
# 求 平 均 值
average = np . mean ( average _ time )
print ( average )
time _ list . append ( average )
# 用 matplotlib 画 图
plt . figure ()
plt . plot (x , time _ list , marker = ’* ’ , label = " binary search ")
plt . show ()
3.3 实验结果
实验数据:
x:1000 y:4.410743713378906e06
x:10000 y:6.4849853515625e06
x:100000 y:1.1849403381347657e05
x:10000000 y:2.0146369934082036e05
由实验可知,二分查找的时间复杂度为 O(logn)。
4. 结论
由实验可知,遍历查找的时间复杂度为 O(n),随样本的大小线性增长。二分查找的时间复杂
度为 O(n)。电脑实际运行图和理论时间复杂度基本一致。当样本容量越来越大时,二分查找增长
的速度比遍历查找慢。由此可知二分查找算法的效率比遍历查找算法的效率高。
参考与致谢
- https://blog.csdn.net/kilotwo/article/details/96274649 Matplotlib 简单上手总结
- https://www.cnblogs.com/yellowgg/p/11272908.html 二分查找的时间复杂度计算