Python算法

一、二分查找1.1 普通的二分查找1.2 带旋转数组的二分查找1.3 搜索旋转排序数组

二、顺序查找三、排序算法3.1 冒泡排序3.1 选择排序3.3 插入排序3.4 快速排序3.5 归并排序3.6 希尔排序

参考链接

一、二分查找

时间复杂度 O(logN)

1.1 普通的二分查找

python算法图解中的解释   通过不断迭代mid的值,来查找参数

def binary_search(nums,target):

# 确定lp和rp的索引值,从两边遍历查找

lp,rp = 0,len(nums)-1

while lp <= rp:

# 迭代求中间的索引值

mid = lp + (rp - lp) // 2

# 如果target等于中间值,返回中间值的索引

if nums[mid] == target:

return mid

# 如果target大于中间值,说明target在中间值的右边

elif target > nums[mid]:

lp = mid + 1

# else最后一种情况,target小于中间值,在其左边,更新rp的值

else:

rp = mid - 1

return None

nums = [1,3,4,56,67,78,980]

print(binary_search(nums,980))

1.2 带旋转数组的二分查找

例题链接: https://leetcode-cn.com/problems/search-in-rotated-sorted-array/

首先判断旋转点在中间值的左边还是右边然后进行二分查找

def xuanzhuan_search(nums,target):

lp,rp = 0,len(nums)-1

while lp <= rp:

mid = lp + (rp-lp)//2

if nums[mid] == target:

return mid

# 中间值大于lp的值,说明旋转点在中间值的右边

elif nums[mid] >= nums[lp]:

if nums[lp] <= target < nums[mid]:

rp = mid - 1

else:

lp = mid + 1

# 旋转点在中间值的左边

else:

if nums[mid] < target <= nums[rp]:

lp = mid + 1

else:

rp = mid - 1

return False

nums = [56,67,78,980,1,3,4]

print(xuanzhuan_search(nums,100))

1.3 搜索旋转排序数组

https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/

由于返回True or False 在重复值上可进行去重操作

class Solution(object):

def search(self, nums, target):

"""

:type nums: List[int]

:type target: int

:rtype: bool

"""

nums = list(set(nums))

lp,rp = 0,len(nums)-1

while lp <= rp:

mid = lp + (rp-lp)//2

if nums[mid] == target:

return True

# 中间值大于lp的值,说明旋转点在中间值的右边

elif nums[mid] >= nums[lp]:

if nums[lp] <= target < nums[mid]:

rp = mid - 1

else:

lp = mid + 1

# 旋转点在中间值的左边

else:

if nums[mid] < target <= nums[rp]:

lp = mid + 1

else:

rp = mid - 1

return False

本题难点就是有重复值,如果nums[mid]==nums[lp]==nums[rp]该怎么处理

class Solution(object):

def search(self, nums, target):

"""

:type nums: List[int]

:type target: int

:rtype: bool

"""

lp,rp = 0,len(nums)-1

while lp <= rp:

mid = lp + (rp-lp)//2

if nums[mid] == target:

return True

# 中间值大于lp的值,说明旋转点在中间值的右边

elif nums[mid] == nums[lp] == nums[rp]:

lp += 1

rp -= 1

elif nums[mid] >= nums[lp]:

if nums[lp] <= target < nums[mid]:

rp = mid - 1

else:

lp = mid + 1

# 旋转点在中间值的左边

else:

if nums[mid] < target <= nums[rp]:

lp = mid + 1

else:

rp = mid - 1

return False

在我们继续分析之前,我们应该注意到,这个算法是分而治之策略的一个很好的例子。分和治意味着我们将问题分成更小的部分,以某种方式解决更小的部分,然后重新组合整个问题以获得结果。 当我们执行列表的二分查找时,我们首先检查中间项。如果我们正在搜索的项小于中间项,我们可以简单地对原始列表的左半部分执行二分查找。同样,如果项大,我们可以执行右半部分的二分查找。 无论哪种方式,都是递归调用二分查找函数。  不过这种递归调用的方法只能查找target值是否存在于数组中,而不能返回其索引或者下标值

def binarySearch(alist, item):

if len(alist) == 0:

return False

else:

midpoint = len(alist)//2

if alist[midpoint]==item:

return True

else:

if item

return binarySearch(alist[:midpoint],item)

else:

return binarySearch(alist[midpoint+1:],item)

testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]

print(binarySearch(testlist, 3))

print(binarySearch(testlist, 13))

二、顺序查找

其实在讲二分查找之前应该讲顺序查找的,但是顺序查找太简单了

def sequentialSearch(alist, item):

pos = 0

found = False

while pos < len(alist) and not found:

if alist[pos] == item:

found = True

else:

pos = pos + 1

return found

def sequentialsearch(nums,target):

for num in nums:

if num == target:

return True

return False

nums = [1, 2, 32, 8, 17, 19, 42, 13, 0]

print(sequentialsearch(nums,8))

print(sequentialsearch(nums,100))

testlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]

print(sequentialSearch(testlist, 3))

print(sequentialSearch(testlist, 13))

时间复杂度O(n)

三、排序算法

3.1 冒泡排序

def bubble_sort(nums):

for i in range(len(nums)):

for j in range(len(nums)-i-1):

if nums[j] > nums[j+1]:

nums[j],nums[j+1] = nums[j+1],nums[j]

return nums

nums = [123,34,231,456,678,343,1,3,56,768]

print(bubble_sort(nums))

确定边界,num从最后一个开始到1

def bubble_sort(nums):

for num in range(len(nums)-1,0,-1):

for j in range(num):

if nums[j] > nums[j+1]:

nums[j],nums[j+1] = nums[j+1],nums[j]

return nums

nums = [123,34,231,456,678,343,1,3,56,768]

print(bubble_sort(nums))

3.1 选择排序

选择排序改进了冒泡排序,每次遍历列表只做一次交换。为了做到这一点,一个选择排序在他遍历时寻找最大的值,并在完成遍历后,将其放置在正确的位置。与冒泡排序一样,在第一次遍历后,最大的项在正确的地方。 第二遍后,下一个最大的就位。遍历 n-1 次排序 n 个项,因为最终项必须在第(n-1)次遍历之后。

def select_sort(nums):

"""

选择排序:每次选择最小值

:param nums: list

:return: list

"""

for i in range(len(nums)-1):

# 确定当前要排序的位置下标

index = i

# 选择剩下数组里最小的数值,和当前下标值进行交换

for j in range(i+1,len(nums)):

if nums[j] < nums[index]:

index = j

nums[index],nums[i] = nums[i],nums[index]

return nums

nums = [123,34,231,456,678,343,1,3,56,768]

print(select_sort(nums))

你可能会看到选择排序与冒泡排序有相同数量的比较,因此也是 O(n^2)。 然而,由于交换数量的减少,选择排序通常在基准研究中执行得更快。 事实上,对于我们的列表,冒泡排序有 20 次交换,而选择排序只有 8 次。

3.3 插入排序

插入排序,尽管仍然是 O(n^2),工作方式略有不同。它始终在列表的较低位置维护一个排序的子列表。然后将每个新项 “插入” 回先前的子列表,使得排序的子列表称为较大的一个项。展示了插入排序过程。 阴影项表示算法进行每次遍历时的有序子列表。每次插入剩下数组的最小值,并在前面数组找位置

def insert_sort(nums):

"""

将每次插入的值排序

:param nums:

:return:

"""

for i in range(1,len(nums)):

value = nums[i]

pre_index = i-1

while pre_index >= 0 and nums[pre_index] > value:

nums[pre_index+1] = nums[pre_index]

pre_index -= 1

nums[pre_index+1] = value

return nums

nums = [3,6,19,15,4,100,368,34,56,78,89]

print(insert_sort(nums))

3.4 快速排序

def quick_sort(nums):

return qsort(nums,0,len(nums)-1)

def qsort(nums,left,right):

if left > right:

return nums

lp,rp = left,right

key = nums[left]

while lp < rp:

while lp < rp and nums[rp] >= key:

rp -= 1

nums[lp] = nums[rp]

while lp < rp and nums[lp] <= key:

lp += 1

nums[rp] = nums[lp]

nums[lp] = key

qsort(nums,left,lp-1)

qsort(nums,lp+1,right)

return nums

nums = [123,34,231,456,678,343,1,3,56,768]

print(quick_sort(nums))

要分析 quickSort 函数,请注意,对于长度为 n 的列表,如果分区总是出现在列表中间,则会再次出现 log⁡n 分区。为了找到分割点,需要针对枢轴值检查 n 个项中的每一个。结果是 nlog⁡n。此外,在归并排序过程中不需要额外的存储器。不幸的是,在最坏的情况下,分裂点可能不在中间,并且可能非常偏向左边或右边,留下非常不均匀的分割。在这种情况下,对 n 个项的列表进行排序划分为对0 个项的列表和 n-1 个项目的列表进行排序。然后将 n-1 个划分的列表排序为大小为0的列表和大小为 n-2 的列表,以此类推。结果是具有递归所需的所有开销的 O(n^2)  ) 排序。之前提到过,有不同的方法来选择枢纽值。特别地,我们可以尝试通过使用称为中值三的技术来减轻一些不均匀分割的可能性。要选择枢轴值,我们将考虑列表中的第一个,中间和最后一个元素。在我们的示例中,这些是54,77和20.现在选择中值,在我们的示例中为54,并将其用于枢轴值(当然,这是我们最初使用的枢轴值)。想法是,在列表中的第一项不属于列表的中间的情况下,中值三将选择更好的“中间”值。当原始列表部分有序时,这将特别有用。我们将此枢轴值选择的实现作为练习。

3.5 归并排序

def merge_sort(nums):

if len(nums) == 1:

return nums

mid = len(nums) // 2

return merge(merge_sort(nums[:mid]),merge_sort(nums[mid:]))

def merge(left,right):

res = []

while len(left) > 0 and len(right) > 0:

if left[0] < right[0]:

res.append(left.pop(0))

else:

res.append(right.pop(0))

res += left

res += right

return res

nums = [3,6,19,15,4,100,368,34,56,78,89]

print(merge_sort(nums))

3.6 希尔排序

def xiersort(nums):

gap = len(nums) // 2

while gap > 0:

for i in range(gap,len(nums)):

current = nums[i]

while i-gap >= 0 and current < nums[i-gap]:

nums[i] = nums[i-gap]

i -= gap

nums[i] = current

gap //= 2

return nums

nums = [3,6,19,15,4,100,368,34,56,78,89]

print(xiersort(nums))

参考链接

1、Python算法图解 2、https://facert.gitbooks.io/python-data-structure-cn/5.%E6%8E%92%E5%BA%8F%E5%92%8C%E6%90%9C%E7%B4%A2/5.4.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/

python中mid_Python算法相关推荐

  1. Python中hash算法

    文章目录 简介 概念 特点 hash有哪些 算法碰撞 加盐防碰撞 加密 hashlib 主要方法 特有方法 使用方法 加盐 crypt 主要方法 使用说明 应用 密码加密 应用一致性校验 简介 概念 ...

  2. python中pca算法_Python使用三种方法实现PCA算法

    主成分分析(PCA) vs 多元判别式分析(MDA) PCA和MDA都是线性变换的方法,二者关系密切.在PCA中,我们寻找数据集中最大化方差的成分,在MDA中,我们对类间最大散布的方向更感兴趣. 一句 ...

  3. python中mid_python中的函数

    1.1 python 函数 1.函数作用 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维 ...

  4. python中hmac算法+sha512

    hamc算法必须有3个值 key:加密秘钥 msg:待加密字符串 func:使用加密的方法 python实现hmac import hmac import hashlib key='iLAgiLklN ...

  5. python中pca算法_使用python的numpy库实现PCA算法

    #!/usr/bin/env python # -*- coding: utf-8 -*- from numpy import * #参数1:特征值向量, #参数2:比率 #返回值:k(符合指定比率的 ...

  6. python语言中的多行注释符是_有没有一种方法可以在Python中创建多行注释? - python...

    我最近开始研究Python,但是找不到如何实现多行注释.大多数语言都有块注释符号,例如 /* */ 我在Python中尝试过此方法,但它引发了错误,因此这可能不是正确的方法. Python实际上是否具 ...

  7. python队列怎么用_如何在Python中使用多处理队列? - python

    我很难理解多处理队列如何在python上工作以及如何实现它.假设我有两个python模块,它们从共享文件中访问数据,我们将这两个模块称为writer和Reader.我的计划是让读取器和写入器都将请求放 ...

  8. python中复制n次字符串_Python正则表达式,如何将字符串匹配n次 - python

    我想匹配包含单词100.00%的行,出现3次. 例如 some string 100.00% foo 100.00% 100.00% some string 99.91% foo 100.00% 99 ...

  9. python指定返回类型_如何在python中指定方法返回类型列表 - python

    假设我有一个类似下面的方法 def validate(self, item:dict, attrs:dict)-> list: 如果我想更具体一点,告诉我我的返回类型是 验证消息? 我应该如何实 ...

最新文章

  1. 整合vs2005sp1到vs2005安装文件中
  2. TimeSpan 时间间隔
  3. 基于文本挖掘的企业隐患排查质量分析模型
  4. tp5,thinkphp5,隐藏index.php,隐藏入口文件
  5. SpringSecurity OAuth2中表结构说明
  6. Ajax拿取html格式数据
  7. Python自动化开发学习22-Django下(Form)
  8. excel vba 从入门到精通_VBA词汇-基本元素篇
  9. java 上传文件到服务器_java上传文件到OSS云服务器(二)
  10. CSDN 勤写标兵勋章 颁发规则
  11. 局域网下搭建项目管理服务器,如何低成本快速搭建局域网地图服务器
  12. 图论及其应用 2009年 期末考试答案 总结
  13. win7开机启动项设置_怎么个性化设置win7系统开机登录画面【详细介绍】
  14. 推荐几个高质量图片网站,再也不怕没图装X了
  15. MyBioSource STMN1 elisa 试剂盒解决方案
  16. 最新百度网盘不限速教程(油猴)
  17. VRTK_Artificial Rotator(人工旋转器)脚本属性详解
  18. ORA-01012: not logged on 解决办法记录错误
  19. ShardingJdbc入门
  20. 苹果好用计算机软件,别让你的苹果电脑再吃灰了,几款小众好用的软件推荐

热门文章

  1. 了解和使用CSS中的rem单位
  2. GitLab版本升级跨大版本
  3. WMI使用小工具——WMI代码生成器
  4. Tera-Store高速数据采集存储系统
  5. 高仿163网站广告弹出层(每天定时24小时弹出一次)
  6. alu和mdr位数相等吗_计算机组成原理复习
  7. Linux中PS1的用法
  8. 通过组策略编辑器关闭Windows自动更新
  9. 一个阳光女孩儿的来信——网上答疑(21)
  10. centos 怎么退出init 3_CentOS 7.3:LAMP 动静分离部署