1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 算法图解/二分查找/简单查找/选择排序/递归算法/快速排序算法/

算法图解/二分查找/简单查找/选择排序/递归算法/快速排序算法/

时间:2020-07-12 03:47:03

相关推荐

算法图解/二分查找/简单查找/选择排序/递归算法/快速排序算法/

大 O 表示法

大 O 表示法在讨论运行时间时,log 指的都是 log2

大 O 表示法指出了算法有多快,让你能够比较操作数,它指出了算法运行时间的增速,而并非以秒为单位的速度。

大 O 表示法指出了最糟情况下的运行时间。

下面按从快到慢的顺序列出了经常会遇到的5种大O运行时间:

O(log n),也叫对数时间,这样的算法包括二分查找O(n),也叫线性时间,这样的算法包括简单查找O(n * log n),这样的算法包括快速排序 —— 一种速度较快的排序算法O(n2),这样的算法包括选择排序 —— 一种速度较慢的排序算法O(n!),这样的算法包括旅行商问题的解决方案 —— 一种非常慢的算法 O(1)

时间复杂度,比如操作一步到位这是常数级别的时间复杂,即为 O(1)。

a = 100 / 2 + 101 * 10 + 5

O(logn)

如下操作,每次 n 会被除以 3,遍历次数等于 以 3 为底 log n 次。在大 O 标记体系中,以 3 为底和以 5 为底没有区别,所以统一标记为 O(logn)。

def f(n):while n > 0:print(n)n //= 3

o(n)

线型复杂度也是很理想的情况,如下面的操作,每次遍历,n 减去 3,这样总共遍历(n-1)/3 + 1 次后算法终止,根据大 O 标记法,算法的时间复杂为 O(n)。

def f(n):while n > 0:print(n)n -= 3

O(nlogn)

如下面所示的两层循环,复杂度便是 nlogn。外层循环的运行次数为 n,里层循环的运行次数为 logn 次,所以一共需要 nlogn 次。

def f(n):for i in range(n):for j in range(1,n,2):print(i*j)

O(n^2)

O(n^2) 是多项式时间复杂度的代表,此类算法的时间复杂度已经难以划分到高效算法集合中,它只能是问题的有效解,而不是高效解。如下两层 for 循环,时间复杂度就是 O(n^2)。

def f(n):for i in range(n):for j in range(n):print(i*j)

O(2^n)

时间复杂度为 O(2^n) 的算法是指数级增长的,此类复杂度下求解的问题往往都是难题,因为随着问题规模 n 的增长,指数级的增长速度是惊人的。

例如经典的旅行商问题,商人要去 n 个地方拜访,如何规划拜访顺序才能使得旅行距离最短。如果仅拜访肉眼可见的两三个地方时,我们还能穷举所有拜访的组合,进而找到最短路径。

但是当问题规模 n 变大时,目前所有的计算机资源总和都难以在有限的时间里计算出最优的最短路径,这类问题的时间复杂度都为指数级,属于 NP 难问题。

二分查找与简单查找

二分查找的输入必须为有序的元素列表,查找的时候每次获取中间的元素。

简单查找则是按照顺序从头至尾的查找每个元素。

一般而言,对于包含n个元素的列表,用二分查找最多需要 log2n 步,而简单查找最多需要n步。

二分查找算法代码如下:

def binary_search(arr, num):arr.sort() # 对输入参数先进行排序print arrlow = 0high = len(arr) - 1while low <= high:# 通过下表缩小范围mid = (low + high)/2if arr[mid] < num:low = mid + 1elif arr[mid] > num:high = mid - 1elif arr[mid] == num:return midelse:return "Not Exists"a = [10, 2, 8, 1, 3, 20, 15]print binary_search(a, 10)#打印值[1, 2, 3, 8, 10, 15, 20]4

选择排序

选择排序的思路大概分为两步:

对要排序的 N 个元素依次进行比较,返回要获取的最大值或者最小值;

将返回的最大值或者最小值添加到新的列表中,在原列表中删除该元素,并继续重复步骤 a,直到原列表中没有元素;

选择排序代码:

def find_min(arr): # 找出最小值min_value = arr[0]index = 1while index <= len(arr) - 1:if arr[index] < min_value:min_value = arr[index]index += 1return min_valuedef select_sort(arr): # 将找到的最小值依次在原列表中删除,并存入新列表dst = []for i in range(len(arr)):min_value = find_min(arr)dst.append(min_value)arr.remove(min_value)return "dst is {0}".format(dst)a = [10, 2, 8, 30, 3, 20, 15]print select_sort(a)# 输出dst is [2, 3, 8, 10, 15, 20, 30]

递归算法

每个递归函数都分为两部分:基线条件和递归条件。

基线条件是指函数的终止条件,即避免形成死循环的部分;递归条件则指的是函数自己调用自己。

计算阶乘的递归函数

def fact(x):if x == 1:return 1else:return x * fact(x-1)print fact(5)

计算斐波那契数列某一项的值

def fibo(n):if n == 0 or n == 1:return nelse:return fibo(n-1) + fibo(n-2)print fibo(7)

快速排序算法

快速排序比选择排序的算法快很多,它可借助递归方法实现,主要步骤如下:

选择基准值;

将待排序的数组分成两个子数组:小于基准值的元素和大于基准值的元素;

分别在对这两个子数组进行快速排序;

def quick_sort(array):if len(array) < 2: # 为空或者只包含一个元素时return arrayelse:base = array[0]# 基准值less = [x for x in array[1:] if x <= base]# 所有小于基准值的元素greater = [y for y in array[1:] if y > base] # 所有大于基准值的元素return quick_sort(less) + [base] + quick_sort(greater) # 对两组数据进行递归排序a = [10, 2, 8, 30, 3, 20, 15]print quick_sort(a)

散列表

散列表也被称为散列映射、映射、字典和关联数组等。在 python 语言中表现为字典形式,要求将同样的输入映射到相同的索引,将不同的输入映射到不同的索引。可将字典用于查找、服务器缓存等场景。

散列表的查找、插入和删除速度都非常快,散列表适合用于模拟映射关系以及用于防止重复。

广度优先搜素

从 A 到 B 地有很多种路径可以到达,但是只有一条路径是最短路径,这种寻找最短、最优路径问题被称为最短路径问题。

解决最短路径问题的算法被称为广度优先搜索。

图由节点和边组成,一个节点可能与众多节点直接相连,这些节点被称为邻居。

广度优先搜索是一种用于图的查找算法,可解决两类问题:

从节点A出发,有前往节点B的路径吗?

从节点A出发,前往节点B的哪条路径最短?

有向图与无向图的区别:

有向图中的边为箭头,箭头的方向指定了关系的方向;

无向图中的边不带箭头,其中的关系是双向的;

广度优先搜索的运行时间为O(人数 + 边数),这通常写作O(V + E),其中V为顶点(vertice)数,E为边数。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。