大 O 表示法

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

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

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

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

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

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

a = 100 / 2 + 101 * 10 + 5
  1. O(logn)

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

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

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

def f(n):while n > 0:print(n)n -= 3
  1. O(nlogn)

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

def f(n):for i in range(n):for j in range(1,n,2):print(i*j)
  1. 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)
  1. 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

选择排序

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

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

  2. 将返回的最大值或者最小值添加到新的列表中,在原列表中删除该元素,并继续重复步骤 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)

快速排序算法

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

  1. 选择基准值;

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

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

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 地有很多种路径可以到达,但是只有一条路径是最短路径,这种寻找最短、最优路径问题被称为最短路径问题。

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

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

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

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

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

有向图与无向图的区别:

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

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

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

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

  1. 算法图解学习笔记02之选择排序

    package 第二章;import java.util.Arrays;//找出列表中最小(大)的,放入新列表(O(n)),再次找 public class SelectionSort {public ...

  2. c++Cocktail Selection Sort鸡尾酒选择排序的实现算法(附完整源码)

    C++Cocktail Selection Sort鸡尾酒选择排序的实现算法 C++Cocktail Selection Sort鸡尾酒选择排序的实现算法完整源码(定义,实现,main函数测试) C+ ...

  3. 对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。

    题目要求: (1)对以下6种常用的内部排序算法进行比较:起泡排序.直接插入排序.简单选择排序.快速排序.希尔排序.堆排序. (2)待排序表的表长不小于100:其中的数据要用伪随机数产生程序产生:至少要 ...

  4. 排序算法:冒泡排序、插入排序、选择排序、希尔排序

    相关博客: 排序算法:冒泡排序.插入排序.选择排序.希尔排序 排序算法:归并排序.快速排序 排序算法:桶排序.计数排序.基数排序 排序算法:堆排序 十大排序算法小结 一.冒泡排序: 1.算法原理: 冒 ...

  5. 冒泡排序,插入排序,选择排序三种算法的优劣

    https://www.jianshu.com/p/9f724c880124 最近听了王争老师的数据结构与算法之美,大有获益,特写此博客与大家分享. 排序算法太多了,但大体可以归结于三类,冒泡排序,插 ...

  6. C语言排序算法 选择排序 插入排序 快速排序 qsort实现快排 堆排序

    常见排序算法 选择排序 选择排序(Selection sort)是一种简单直观的排序算法. 它的工作原理如下. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素 ...

  7. JS 排序算法详解(冒泡排序,选择排序,插入排序,希尔排序,快速排序)

    JS 排序算法详解(冒泡排序,选择排序,插入排序,希尔排序,快速排序) 一. 大O表示法 在进行排序算法之前,我们得先掌握一种对算法效率的表示方法,大O表示法. 我们使用大O表示法来表示算法的时间复杂 ...

  8. 经典排序算法(一) —— Selection Sort 选择排序

    经典排序算法(一) -- Selection Sort 选择排序 文章目录 经典排序算法(一) -- Selection Sort 选择排序 简介 排序过程 实现 复杂度 简介 选择排序是一种简单直观 ...

  9. java排序算法(插入排序,冒泡排序,选择排序)

    java排序算法(插入排序,冒泡排序,选择排序) 先了解原理,然后自己跟着敲一下,加深印象 CMD编译命令:javac -encoding utf-8 SortList.java && ...

最新文章

  1. Flask-Migrate拓展数据库表结构
  2. JDK 8 新特性 之 函数接口
  3. BZOJ5343 [Ctsc2018]混合果汁 【二分 + 主席树】
  4. mysql生成随机时间
  5. 视觉SLAM笔记(56) 位姿图优化
  6. Golang配置文件解析-oozgconf
  7. 脾虚怎么办?7招驯服“脾”气-转
  8. python打开word内对象_Python操作Word:常用对象介绍
  9. 如何在双显示器设置中将 Mac Dock 保持在一个屏幕上?
  10. CentOS6.5配置网络
  11. MSDEV.EXE-应用程序错误解决办法(转)
  12. 安装签名不一致什么意思_探灵之夜嫁安装失败签名不一致怎么办-夜嫁安装失败签名不一致解决方法-松松手游网...
  13. textbox wpf 居中_C# + WPF: TextBox中的光标定位问题
  14. 曾宪武《物联网通信技术》课后答案(一)
  15. 中兴ZXV10 B860AV1.1 全TTL操作完美破解
  16. SOSO发布国内首家高清街景地图 引领地图换代
  17. 创始人和VC疯狂撕逼,究竟所为何事?
  18. 文件上传(WebUploader)成功之前自定义裁剪(vue-img-cutter),上传裁剪的图片,并兼容ie
  19. DNS A记录 NS记录 CNAME记录 TXT记录 TTL值
  20. openwrt之initramfs-kernel

热门文章

  1. 2022-2028年中国非溶聚丁苯橡胶行业市场竞争态势及发展前景分析报告
  2. 2022-2028年中国橡胶板的制造行业发展战略规划及投资方向研究报告
  3. 2022-2028年中国塑料合成革的制造行业市场全景评估及发展趋势研究报告
  4. Python 标准库之 fcntl
  5. 超详细中文预训练模型ERNIE使用指南-源码
  6. TVM apps extension示例扩展库
  7. CVPR2020:三维实例分割与目标检测
  8. 2021年大数据Spark(二十二):内核原理
  9. 微信小程序setData()方法的使用
  10. TabLayout 遇到那些坑 tab标签不显示问题