python算法题排序_python-数据结构与算法- 面试常考排序算法题-快排-冒泡-堆排-二分-选择等...

算法可视化网站推荐---->visualgo

0.面试题中的排序算法

一些排序算法可能在工作中用的会比较少,但是面试却是不得不面对的问题。算法有助于提高我们对数据结构的理解以及提高自己的逻辑能力,没事刷刷真的不错。

1.快排

面试最推荐而且也是写的最多的

快排的思路是分而治之,相当于我每次去将一个数归为,直到所有的数都归为了,那么这个排序也就成功了。

快排第一种思路:(这个思路参考下,不要写)

平均时间复杂度

最好时间复杂度

最坏时间复杂度

空间复杂度

排序方式

O(nlogn)

O(nlogn)

O(n2)

O(nlogn)

in-place

import random

def quickSort(nums): # 这种写法的平均空间复杂度为 O(nlogn),时间复杂度为O(nlogn)

if len(nums) <= 1:

return nums

mid = nums[0] # 基准值

left = [nums[i] for i in range(1, len(nums)) if nums[i] < mid]

right = [nums[i] for i in range(1, len(nums)) if nums[i] >= mid]

return quickSort(left) + [mid] + quickSort(right)

li = list(range(100))

random.shuffle(li)

print(li)

print(quickSort(li))

这个利用到了递归,分而治之,但是这个算法的空间复杂度较高,有可以优化的点。在做算法题的时候,对于列表字典这些可变数据结构,一定要明白如何去利用这些数据结构本身的内存而不是再去开辟很多新的内存。

快排第二种思路:

平均时间复杂度

最好时间复杂度

最坏时间复杂度

空间复杂度

排序方式

O(nlogn)

O(nlogn)

O(n2)

O(log)

in-place

import random

class Solution(object):

"""

快排

时间复杂度为O(nlogn),最差情况为O(n2)

空间复杂度为O(logn)

"""

def partition(self, li: list, left, right):

tmp = li[left]

while left < right:

while left < right and li[right] >= tmp:

right -= 1

li[left] = li[right]

while left < right and li[left] <= tmp:

left += 1

li[right] = li[left]

li[left] = tmp

return left

def quick_sort(self, li, left, right):

if left < right:

mid = self.partition(li, left, right)

self.quick_sort(li, left, mid - 1)

self.quick_sort(li, mid + 1, right)

li = list(range(100))

random.shuffle(li)

print(li)

solution = Solution()

print(solution.quick_sort(li, 0, len(li) - 1))

print(li)

与第一种方法不同的点就是在于对空间的利用,利用了li本身的内存空间。

写在同一个函数里

如何把他们写在同一个函数里并且有一个new idea,在找到两边各一个不属于各自位置的值后,进行交换。

def quick_sort(li, start, end):

if start >= end:

return

left, right = start, end

tmp = li[left]

while left < right:

# 设置一个基准点

while left < right:

while left < right and li[right] >= tmp: # 至少要一个等号,不然会出现死循环

right -= 1

li[left] = li[right]

while left < right and li[left] <= tmp: # 因为如果没有一边有等号,当列表中有两个相同值的时候,就无法跳出循环

left += 1

li[right] = li[left]

li[left] = tmp

quick_sort(li, start, left - 1)

quick_sort(li, left + 1, end)

if __name__ == '__main__':

import random

li = list(range(100))

li.append(55)

random.shuffle(li)

print(li)

print(quick_sort(li, 0, 99))

print(li)

顺便把参数数量也降低一下:

def quick_sort(li):

def _quick_sort(li, start, end):

if start >= end:

return

left, right = start, end

tmp = li[left]

while left < right:

# 设置一个基准点

while left < right:

while left < right and li[right] >= tmp: # 至少要一个等号,不然会出现死循环

right -= 1

li[left] = li[right]

while left < right and li[left] <= tmp: # 因为如果没有一边有等号,当列表中有两个相同值的时候,就无法跳出循环

left += 1

li[right] = li[left]

li[left] = tmp

_quick_sort(li, start, left - 1)

_quick_sort(li, left + 1, end)

_quick_sort(li, 0, len(li)-1)

2.冒泡排序

平均时间复杂度

最好时间复杂度

最坏时间复杂度

空间复杂度

排序方式

O(n2)

O(n)

O(n2)

O(1)

in-place

理解的关键点在于左半部分是有序区。

冒泡作为最简单的排序算法之一,面试的时候万不得已(其他的都记不住了),还是不要写。写个快排能好多了。

import random

class Solution(object):

"""

冒泡排序

"""

@staticmethod

def bubble_sort(li):

for i in range(len(li) - 1): # 交换的次数

flag = True # flag的作用是当这个序列就是一个升序(这边排的是升序),那么久可以降低时间复杂度到O(n)

for j in range(len(li) - i - 1): # 剩余需要交换的元素

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

li[j], li[j + 1] = li[j + 1], li[j]

flag = False

if flag:

return li

return li

li = list(range(100))

random.shuffle(li)

print(li)

solution = Solution()

solution.bubble_sort(li)

print(li)

3.选择排序

平均时间复杂度

最好时间复杂度

最坏时间复杂度

空间复杂度

排序方式

O(n2)

O(n2)

O(n2)

O(1)

in-place

选择排序主要需要注意点是左边部分是有序区。

也不推荐写,时间复杂度高,效率低,太简单了。

import random

class Solution(object):

"""

选择排序

"""

def select_sort(self, li):

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

min_pos = i

for j in range(i+1, len(li)): # 左部分是有序区

if li[min_pos] > li[j]:

min_pos = j

li[i], li[min_pos] = li[min_pos], li[i]

return li

li = list(range(100))

random.shuffle(li)

print(Solution().select_sort(li))

4.插入排序

插入排序如同打扑克一样,每次将后面的牌插到前面已经排好序的牌中。使得左半部分为有序区域。

平均时间复杂度

最好时间复杂度

最坏时间复杂度

空间复杂度

排序方式

O(n2)

O(n2)

O(n2)

O(1)

in-place

import random

def insert_sort(li):

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

# i 表示趟数 还表示摸到牌的位置

j = i - 1 # 取到摸到牌的前一张,也就是有序位置的最后一张牌

tmp = li[i]

while j >= 0 and li[j] > tmp:

# 两个终止条件: 1. j==-1 2. j位置的值小于等于tmp

li[j + 1] = li[j]

j -= 1

li[j + 1] = tmp

li = list(range(10000))

random.shuffle(li)

insert_sort(li)

print(li)

5.堆排序(Heap Sort)

import random

def sift(li, low, high):

"""

堆调整程序

:param li:

:param low:

:param high:

:return:

"""

tmp = li[low]

i = low

j = 2 * i + 1

while j <= high: # 第一个退出条件:j不存在

if j + 1 <= high and li[j + 1] > li[j]: # 如果右孩子存在并且右孩子比左孩子大

j += 1 # j指向右孩子

if li[j] > tmp:

li[i] = li[j]

i = j

j = 2 * i + 1

else: # 第二个退出条件:j位置的值比tmp小

break

li[i] = tmp

def heap_sort(li):

# 1. 建堆

n = len(li)

for i in range(n // 2 - 1, -1, -1): # i表示遍历的low

sift(li, i, n - 1) # low:i high:统一写成最后一个位置对正确性没有影响

# 2. 挨个出数:退休 棋子 调整

for i in range(n - 1, 0, -1): # i 表示当前位置堆的high

li[i], li[0] = li[0], li[i]

sift(li, 0, i - 1)

# print(li)

li = list(range(100000))

random.shuffle(li)

heap_sort(li)

print(li)

6.二分查找

二分查找非常简单,是建立在列表有序的情况下,利用二分法不断逼近目标值的。

def binary_search(li, target):

left = 0

right = len(li) - 1

while left <= right:

mid = (right - left) // 2 # 取一个中间值

if target > li[mid]:

left = mid + 1 # 如果比目标值比中位值还要大,调整右边界指针

elif target < li[mid]:

right = mid - 1 # 如果比目标值比中位值要小,调整左边界指针

else:

return mid

return -1

算法的稳定性

选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/504292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode笔记】31. 下一个排列(Java、原地算法、偏数学)

文章目录题目描述思路 && 代码二刷打卡第八天&#xff5e; 题目描述 需要花点时间思考的一道题&#xff0c;这篇题解写得很好。 思路 && 代码 主要分为这三个步骤&#xff1a; 从后往前找到满足 nums[first] < nums[first 1] 的索引 first从后往前找到…

【LeetCode笔记】剑指Offer 43. 1~n 整数中1出现的次数(Java、数位dp、偏数学)

文章目录题目描述思路 && 代码二刷打卡第九天啦&#xff5e; 题目描述 有点像数字序列中的某一位 思路 && 代码 主体思路&#xff1a;从低到高&#xff0c;计算出每一位出现的1的个数。三种情况&#xff1a;n的当前位为0、为1、为其他值。这里和数位dp的思…

wsadata wsadata;为什么不通过_注册公司之公司名称核准,知道为什么你的核名一直不通过吗?...

您可能会问&#xff0c;公司名字为什么要先“核名”&#xff1f;所有公司名字&#xff0c;必须经过工商局审核&#xff0c;审核通过才能使用&#xff01;注册公司的第一步就是为公司起一个好听又有内涵的名字&#xff0c;实际注册时往往核名很难通过&#xff0c;今天就来聊聊注…

【LeetCode笔记】剑指Offer 51. 数组中的逆序对(Java、分治)

题目描述 多说无益&#xff5e;直接冲代码吧&#xff01; 思路 && 代码 1. 暴力 O(n2n^2n2) 乍一看这题目&#xff0c;很难不直接用暴力法冲一冲&#xff08;也就双层循环的事&#xff09;但是不出意料地超时啦&#xff5e;想一想&#xff0c;O(n2n^2n2)会超时&am…

python云计算服务_python 云计算平台

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":6,"count":6}]},"card":[{"des":"云服务器 ECS(Elastic Compute Service)是一…

【LeetCode笔记】剑指Offer 59. I 滑动窗口的最大值(Java、单调队列)

文章目录题目描述思路 && 代码1. 暴力法 O(n2n^2n2) && O(1)2. 单调队列辅助 O(n) && O(n)二刷打卡第十天&#xff5e; 题目描述 久违的滑动窗口题&#xff01; 思路 && 代码 1. 暴力法 O(n2n^2n2) && O(1) 老规矩&#xff0c;先…

python args kwargs 理解_*args和**kwargs在python中的作用

我发现PYTHON新手在理解*args和**kwargs这两个魔法变量的时候有些困难。他们到底是什么呢&#xff1f;首先&#xff0c;我先告诉大家一件事情&#xff0c;完整地写*args和**kwargs是不必要的&#xff0c;我们可以只写*和**。你也可以写*var和**vars。写*args和**kwargs只是一个…

【LeetCode笔记】剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)

文章目录题目描述知识点1. 优先队列2. Java 中 queue 的 offer、poll 等区别思路 && 代码二刷打卡第十一天&#xff5e; 题目描述 虽然但是&#xff0c;这是一道很nice的题目&#xff08;涉及的知识点、运用很实用&#xff0c;见知识点模块&#xff09; 知识点 1.…

python合并视频和音频_真没想到,Python 还能实现 5 毛特效

作者 | ZackSock来源 | ZackSock(ID:ZackSock)Python牛已经不是一天两天的事了&#xff0c;但是我开始也没想到&#xff0c;Python能这么牛。前段时间接触了一个批量抠图的模型库&#xff0c;而后在一些视频中找到灵感&#xff0c;觉得应该可以通过抠图的方式&#xff0c;给视频…

【前端知识学习】HTML5 学习笔记

文章目录一. 简介与基本信息1. W3C 标准2. HTML基本结构3. 网页基本信息4. 网页基本标签5. 媒体元素二. 网页结构与框架1. 页面结构2. iframe 内联框架3. 表单这是狂神的HTML教学的笔记。从今天开始转行前端 主要是为了把简历写得更好看 &#xff0c;因此部分地方会比较省略&am…

高大上的集团名字_那些刚改了“高大上”名字的学校,你知道都有哪些吗?蜻蜓AI小编来帮你科普一下...

升学心里没底&#xff0c;蜻蜓探长帮你&#xff01;家长和考生想必在报考之前都会对院校进行一定的了解&#xff0c;所谓的了解&#xff0c;不过是在官网上查一查学校的院校最低分数和专业最低分数。最容易看到的往往是这个院校最表面的东西&#xff0c;然而我们对院校的了解只…

【LeetCode笔记】剑指Offer 19. 正则表达式匹配(Java、动态规划)

文章目录题目描述思路 && 代码二刷打卡第十二天&#xff5e; 题目描述 拖了超级久的一道题 &#xff0c;懒得看正则表达式&#xff0c;但是其实和正则表达式相关的地方也不多 思路 && 代码 参照这篇题解写的&#xff0c;dalao属实万物皆可动态规划。主要是…

怎么制作游戏脚本_精彩的游戏视频混剪怎么做?录屏剪辑一站式制作

英雄联盟LOL这么多年深受广大玩家喜爱&#xff0c;而且各大平台上更不乏游戏精彩视频集锦&#xff0c;更有一些视频创作者通过小视频一鸣惊人。那么&#xff0c;这些精彩的游戏视频是怎么制作出来的呢&#xff1f;你离他们只是缺了这个工具而已。今天&#xff0c;小编给大家推荐…

【LeetCode笔记】剑指Offer 37. 序列化二叉树(Java、二叉树、序列化、BFS、队列)

文章目录题目描述思路 && 代码二刷题目描述 这道题涉及到不少 String、StringBuilder、Integer的转换、处理。 思路 && 代码 序列化&#xff1a;迭代进行一个层序遍历&#xff0c;逐个加入结果字符串中。反序列化&#xff1a;根据序列化得到的结果字符串&a…

python设计模式免费_python 设计模式

标签&#xff1a;介绍设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问&#xff0c;设计模式于己于他人于系统都是多赢的&#xff0c;设计模式…

【LeetCode笔记】72. 编辑距离(Java、字符串、动态规划)

文章目录题目描述思路 && 代码 O(n2n^2n2)、O(n2n^2n2)二刷打卡第十三天&#xff5e; 题目描述 感觉和正则表达式匹配这道题很像&#xff1a;同样的两个字符串&#xff0c;同样的二维数组dp&#xff0c;同样的hard。。 思路 && 代码 O(n2n^2n2)、O(n2n^2n2…

超级外链工具_哪些SEO排名工具是有效的呢?

SEO的发展到现在已经有十多年的时间&#xff0c;出现的大大小小的SEO工具也有上百种&#xff0c;这些SEO工具的背景和作用是不同的。大致可以分为两类&#xff1a;一类是SEO建议工具&#xff0c;帮助诊断网站给出优化分析建议&#xff1b;另一类是可以直接帮助网站排名的工具&a…

【LeetCode笔记】416. 分割等和子集(Java、动态规划、背包问题、滚动数组)

文章目录题目描述思路 && 代码1. 动态规划 O(nc) 、O(nc)2. 结合滚动数组 O(nc)、O(c)二刷打卡第十四天&#xff5e;熬夜也得把题目补上 题目描述 初看题目&#xff0c;想到的思路是用记忆化DFS来找结果来着。。看了题解才知道是背包问题 思路 && 代码 1…

python 网络摄像头安装图解_网络摄像头在opencv-python和opencv-contrib-python...

我一直在使用anaconda在python中的opencv中遇到网络摄像头问题.问题如下&#xff1a;如果通过以下两种方式之一安装了opencv,则无法打开网络摄像头&#xff1a;pip install opencv-python(可用的3.1、3.2、3.3),或pip install opencv-contrib-python(可用3.2,3.3)但是,只有当我…

【LeetCode笔记】494. 目标和(Java、动态规划、背包问题、滚动数组)

文章目录题目描述思路 && 代码1. 动态规划 O(n2n^2n2)、O(n2n^2n2)&#xff08;最方便理解&#xff0c;初版&#xff09;2. 转换成 01 背包问题 O(n2n^2n2)、O(nnn)二刷离谱&#xff01;添加了测试用例&#xff0c;上面的代码需要添加负数条件了&#xff08;见下面的代…