查找 排序算法(系列)

news2025/1/11 12:35:18

复习一下排序算法吧,数据结构有点难,虽然我已经看过一遍了,重温一遍还是很有收获!

本文会出一系列(主讲算法排序),欢迎订阅!!!

Python中常用的排序算法有以下几种:

  1. 冒泡排序(Bubble Sort):通过相邻元素的比较和交换来进行排序。时间复杂度为O(n^2)。

  2. 选择排序(Selection Sort):每次从待排序的元素中选择最小(或最大)的元素放到已排序的末尾。时间复杂度为O(n^2)。

  3. 插入排序(Insertion Sort):将待排序的元素逐步插入已排序的序列中,通过比较和交换来进行排序。时间复杂度为O(n^2)。

  4. 快速排序(Quick Sort):通过分治的思想将待排序的序列划分为左右两个子序列,再对子序列进行递归排序。时间复杂度为O(nlogn)。

  5. 归并排序(Merge Sort):将待排序的序列逐步划分为更小的子序列,再将子序列两两合并并排序。时间复杂度为O(nlogn)。

  6. 堆排序(Heap Sort):利用堆数据结构来进行排序,通过构建最大(或最小)堆,并逐步取出堆顶元素来排序。时间复杂度为O(nlogn)。

  7. 希尔排序(Shell Sort):将待排序的序列分组进行排序,然后逐步减小分组的间隔直到为1,最后再进行一次完整的插入排序。时间复杂度为O(nlogn)。

  8. 计数排序(Counting Sort):统计待排序序列中每个元素出现的次数,根据计数结果重新排序。时间复杂度为O(n+k),其中k为序列中的最大值。

  9. 桶排序(Bucket Sort):将待排序的元素根据某个映射函数分到不同的桶中,对每个桶中的元素进行排序,再依次取出桶中的元素。时间复杂度为O(n+k),其中k为桶的个数。

  10. 基数排序(Radix Sort):将待排序的元素按照位数从低到高依次进行排序,根据每个元素的该位数字进行桶排序,最后得到排序结果。时间复杂度为O(d*(n+k)),其中d为位数,k为桶的个数。

以上是Python中常见的排序算法,不同的排序算法适用于不同的场景,选择合适的排序算法可以提高排序效率。

目录

1.顺序查找(Linear Search)

Linear Search

for i,v in enumerate(li)

2.二分查找(必须是有序的)

3.排序的介绍

列表排序

常见的排序算法

LOW B三人组:

4.冒泡排序(Bubble sort)

Bubble sort(原地排序)

改进

5.选择排序

select_sort(时间复杂度O(n^2))

改进版:时间复杂度O(n^2)

6.插入排序(O(n^2))

NB三人组:

7.快速排序(O(nlogn))

8.堆排序(O(nlogn))

堆排序前传:二叉树的存储方式

堆排序前传堆和堆的向下调整

堆排序以及内置模块(heapq)

归并排序:

归并条件、定义、代码

归并排序:(O(nlogn))

总结:


1.顺序查找(Linear Search)

Linear Search

也称线性查找,也就是遍历,从列表首个元素开始,顺序进行搜索,直到找到元素或搜索到列表最后一个元素为止。

时间复杂度为O(n)

# 顺序查找
def Linear_search(li,value):
    for i,v in enumerate(li):
        if v == value:
            return i
    else:
        return None

for i,v in enumerate(li)

Python 线性查找错误 - 豆包

2.二分查找(必须是有序的)

因为:存在循环减半的情况,所以复杂度是O(logn)

while left <= right: mid = (left + right) // # 二分查找

def erfen_reach(li, value):
    left = 0
    right = len(li) - 1
    # mid = (left+right)//2
    while left <= right:
        mid = (left + right) // 2
        if li[mid] == value:
            return mid
        elif value > li[mid]:
            left = mid + 1
        else:
            right = mid - 1
    else:
        return None


li = [1, 2, 3, 4, 5, 6]
print(erfen_reach(li,3))

3.排序的介绍

low B三人组的时间复杂度都是O(n^2),都是原地排序

列表排序

内置排序函数:sort()

常见的排序算法

LOW B三人组:

4.冒泡排序(Bubble sort)

Bubble sort(原地排序)

循环一次选出最大的数

升序:时间复杂度是O(n^2)

# 冒泡排序
import random
def Bubble_sort(li):
    for i in range(len(li)-1):      # i表示趟数
        for j in range(len(li)-i-1):        # j表示箭头
            if li[j] > li[j+1]:
                li[j],li[j+1] = li[j+1],li[j]
​
li = [random.randint(0,1000)for i in range(1000)]
print(li)
Bubble_sort(li)
print(li)

改进

如果我的无序区一趟下来没有发生交换说明我的列表已经是有序的了,所以可以进行改进:

设置一个标志位

# 冒泡排序
import random
def Bubble_sort(li):
    for i in range(len(li)-1):      # i表示趟数
        exchange = False        # 标示位
        for j in range(len(li)-i-1):        # j表示箭头
            if li[j] > li[j+1]:
                li[j],li[j+1] = li[j+1],li[j]
                exchange = True
        print(li)
        if not exchange:
            return
​
# li = [random.randint(0,1000)for i in range(1000)]
li = [1,2,3,4,5,6,7]
# print(li)
Bubble_sort(li)
print(li)

5.选择排序

select_sort(时间复杂度O(n^2))

需要另外开辟空间

# 选择列表
def select_sort(li):
    new_li = []
    for i in range(len(li)):
        min_ele = min(li)
        new_li.append(min_ele)
        li.remove(min_ele)
    return new_li
​
li = [5,4,7,9,6,3,21]
print(select_sort(li))

改进版:时间复杂度O(n^2)

但是不需要另外开辟空间

算法关键点:有序区位置和无序区位置,记录无序区的最小值的位置

def select_sort(li):
    for i in range(len(li)-1):      # i表示趟数
        min_xiaiao = i      # 假定无序区第一个元素是最小值
        for j in range(i+1,len(li)):
            if li[min_xiaiao] > li[j]:
                # 位置发生交换
                min_xiaiao = j
        # 值交换
        li[i],li[min_xiaiao] = li[min_xiaiao],li[i]
​
​
li = [5,4,7,9,6,3,21]
select_sort(li)
print(li)

6.插入排序(O(n^2))

类似于摸牌然后将其插入到手中的牌

# 插入排序
def insert_search(li):
    for i in range(1,len(li)):      # i 表示趟数,也表示未排序的数的下标
        temp = li[i]        # 用于存储将要排序的数
        j = i-1     # 表示已排序好的数下标
        while j >= 0 and li[j] > temp:          # 找出能够插入的位置
            li[j+1] = li[j]         # 向右移动 空出位置放置li[i]
            j -= 1              # 下标向前指 继续比较
        li[j+1] = temp
​
​
li = [5,2,4,6,9,8,5]
insert_search(li)
print(li)

NB三人组:

7.快速排序(O(nlogn))

思想:有一个数将列表分为左右两部分,使得左边的数都比这个数小,右边的数都比这个数大,递归思想继续循环“列表”。

# 快速排序
def quick_sort(li,left,right):
    if left < right:        # 说明至少有两个元素需要排列
        mid = partition(li,left,right)            # 返回的是中间值的下标
        quick_sort(li,left,mid-1)
        quick_sort(li,mid+1,right)
​
def partition(li,left,right):
    temp = li[left]         # 用于存储将列表划分为两部分的那个数
    while left < right:
        while left < right and li[right] >= temp:            # 找出右边比temp小的值放在左边
            right -= 1
        li[left] = li[right]
​
        while left < right and li[left] <= temp:             # 找出左边比temp大的值放在右边
            left += 1
        li[right] = li[left]
​
    li[left] = temp         # 归位
    return left
​
li = [5,2,3,6,8,9,4,2]
quick_sort(li,0,len(li)-1)
print(li)

缺点:

1.递归

2.最坏情况:选择的是最大的数

8.堆排序(O(nlogn))

堆排序前传:二叉树的存储方式

链式存储

顺序存储

堆排序前传堆和堆的向下调整

堆:一种特殊的完全二叉树

大根堆:满足任一节点都比其孩子节点大

小根堆:满足任一节点都比其孩子节点小

堆的向下调整:

假设:节点的左右子树都是堆,但自身不是堆

当根节点的左右子树都是堆时,可以通过一次向下的调整来将其换成一个堆。

堆排序:

堆排序以及内置模块(heapq)

# 堆排序
def sift(li,low,high):
    """
    :param li: 列表
    :param low: 堆的根节点位置
    :param high: 堆的最后一个元素的位置
    :return:
    """
    i = low     # 开始指向根节点
    j = low * 2 + 1         # j开始是左孩子
    temp = li[low]          # temp 把堆顶存储起来
    while j <= high:           # 保证不越界
        if j+1 <= high and li[j+1] > li[j]:     # 右孩子比左孩子大,还得保证有右孩子否则存在越界的情况
            j = j+1             # j指向右孩子
        if li[j] > temp:
            li[i] = li[j]
            i = j
            j = 2*i+1
        else:
            li[i] = temp            # 把temp放到某一个根节点上,但是没有考虑到循环到最后,放置到最后的位置上
            break
    else:
        li[i] = temp            # 把temp放到叶子结点上
​
​
def heap_sort(li):
    n = len(li)
    # 建堆 农村包围城市 从最后一个根节点开始构建堆 i表示根节点下标
    # 最后一个非叶子节点下标是n-1 由父亲找孩子下标(n-1-1)//2
    for i in range((n-2)//2,-1,-1):
        sift(li,i,n-1)
    # 建堆完成
    print(li)
    
    
    # 挨个出数
    for i in range(n-1,-1,-1):          # i指向当前堆的最后一个元素
        li[0],li[i] = li[i],li[0]
        sift(li,0,i-1)          # i-1是新的high
​
​
​
li = [i for i in range(100)]
import random
random.shuffle(li)      # 打乱
print(li)
heap_sort(li)
print(li)

[55, 14, 76, 69, 61, 30, 7, 88, 2, 83, 60, 77, 40, 58, 87, 16, 78, 53, 62, 46, 94, 22, 79, 37, 59, 4, 96, 50, 92, 85, 80, 6, 25, 97, 68, 29, 32, 42, 66, 74, 86, 47, 99, 17, 52, 56, 67, 57, 8, 81, 45, 26, 38, 13, 0, 41, 10, 21, 35, 84, 98, 49, 31, 36, 70, 33, 15, 65, 43, 34, 91, 93, 48, 89, 9, 63, 75, 11, 28, 24, 73, 5, 12, 90, 95, 44, 39, 3, 51, 72, 23, 64, 27, 1, 54, 18, 19, 82, 71, 20]

[99, 97, 98, 93, 95, 96, 92, 91, 89, 94, 79, 82, 40, 76, 87, 70, 88, 55, 75, 86, 90, 72, 67, 77, 81, 38, 30, 50, 58, 85, 80, 36, 33, 78, 69, 53, 32, 63, 66, 74, 46, 83, 61, 51, 52, 64, 60, 57, 71, 59, 45, 26, 4, 13, 0, 41, 10, 21, 35, 84, 7, 49, 31, 16, 6, 25, 15, 65, 43, 34, 68, 29, 48, 2, 9, 62, 42, 11, 28, 24, 73, 5, 12, 14, 47, 44, 39, 3, 17, 22, 23, 56, 27, 1, 54, 18, 19, 8, 37, 20]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

# 堆排序的内置模块
import heapq        # q优先队列(小的先出或者大的先出)
import random
​
​
li = list(range(100))
random.shuffle(li)
print(li)
​
heapq.heapify(li)       # 创建堆
n = len(li)
# 默认是小根堆
for i in range(n):
    print(heapq.heappop(li),end=',')

[77, 36, 60, 69, 24, 49, 99, 35, 92, 53, 68, 15, 19, 43, 4, 45, 87, 89, 18, 10, 5, 30, 63, 54, 21, 16, 13, 3, 29, 88, 17, 76, 67, 64, 85, 52, 41, 84, 75, 62, 1, 28, 72, 11, 26, 25, 33, 9, 81, 6, 56, 74, 51, 97, 98, 20, 70, 22, 59, 94, 2, 32, 66, 55, 14, 58, 42, 34, 82, 23, 83, 39, 8, 31, 37, 47, 40, 96, 50, 0, 48, 57, 46, 71, 65, 38, 80, 78, 44, 79, 91, 93, 86, 90, 61, 95, 27, 73, 12, 7] 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99, 进程已结束,退出代码为 0

归并排序:

归并条件、定义、代码

# 归并:
def merge(li,low,mid,high):
    i = low
    j = mid + 1
    heap = []
    while i <= mid and j <= high:
        if li[i] < li[j]:
            heap.append(li[i])
            i += 1
        else:
            heap.append(li[j])
            j += 1
    while i <= mid:
        heap.append(li[i])
        i += 1
    while j <= high:
        heap.append(li[j])
        j += 1
    li[low:high+1] = heap
​
​
li = [2,5,7,8,9,1,3,4,6,10]
merge(li,0,4,9)
print(li)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

归并排序:(O(nlogn))

空间复杂度是:O(n)

# 归并:
def merge(li,low,mid,high):
    i = low
    j = mid + 1
    heap = []
    while i <= mid and j <= high:
        if li[i] < li[j]:
            heap.append(li[i])
            i += 1
        else:
            heap.append(li[j])
            j += 1
    while i <= mid:
        heap.append(li[i])
        i += 1
    while j <= high:
        heap.append(li[j])
        j += 1
    li[low:high+1] = heap
​
​
def merge_sort(li,low,high):
    if low < high:          # 至少有两个元素
        mid = (low+high)//2
        merge_sort(li,low,mid)
        merge_sort(li,mid+1,high)
        merge(li,low,mid,high)
​
​
li = list(range(100))
import random
random.shuffle(li)
print(li)
merge_sort(li,0,len(li)-1)
print(li)

[72, 79, 74, 75, 93, 83, 2, 57, 56, 43, 20, 24, 19, 14, 89, 11, 3, 88, 34, 66, 58, 52, 68, 38, 47, 99, 15, 7, 31, 86, 10, 64, 40, 41, 12, 33, 18, 62, 54, 42, 70, 30, 1, 49, 51, 92, 53, 46, 87, 32, 6, 16, 73, 78, 59, 98, 26, 39, 44, 23, 22, 5, 69, 77, 85, 94, 80, 50, 9, 63, 45, 8, 91, 97, 29, 0, 4, 96, 48, 60, 36, 35, 67, 13, 65, 25, 81, 27, 55, 95, 21, 82, 28, 71, 17, 37, 76, 61, 90, 84] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

总结:

稳定性:挨个移动位置的都是稳定的,不挨个飞着换的都是不稳定的。

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

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

相关文章

Y20030053 JSP+SSM+MYSQL+LW+旅游系统的设计与实现 源码 配置 文档 全套资料

旅游系统的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 摘 要 随着旅游业的蓬勃发展和人们对休闲度假需求的不断增加&#xff0c;旅游业管理面临着越来越多的挑战。为了提高管理效率、优化客户体验并增强市场竞争力&#xff0c;本文介绍…

3D 生成重建016-SA3D从nerf中分割一切

3D 生成重建016-SA3D从nerf中分割一切 文章目录 0 论文工作1 方法介绍2 实验结果 0 论文工作 1 SAM的背景和目标&#xff1a; SAM 是一种强大的二维视觉基础模型&#xff0c;能够在 2D 图像中进行任意物体的分割。传统上&#xff0c;SAM 在二维空间表现出色&#xff0c;但其无…

Leetcode—374. 猜数字大小【简单】

2024每日刷题&#xff08;202&#xff09; Leetcode—374. 猜数字大小 C实现代码 /** * Forward declaration of guess API.* param num your guess* return -1 if num is higher than the picked number* 1 if num is lower than the picked number* …

数字孪生与大型模型强强联合,共塑工业制造崭新前景

随着新一代信息技术与实体经济的加速融合&#xff0c;工业领域的数字化、智能化转型趋势愈发显著&#xff0c;孕育出一系列制造业数字化转型的新模式与新业态。在此背景下&#xff0c;数字孪生技术作为关键支撑力量&#xff0c;正在全球范围内迅速崛起并得到广泛应用&#xff0…

vue+mars3d点击图层展示炫酷的popup弹窗

展示效果 目录 一&#xff1a;叠加数据图层到地图上&#xff0c;此时需要使用bindPopup绑定popup 二、封装自定义的popup&#xff0c;样式可以自行调整 一&#xff1a;叠加数据图层到地图上&#xff0c;此时需要使用bindPopup绑定popup 这里我根据数据不同&#xff0c;展示的…

springboot利用easypoi实现简单导出Excel

vue springboot利用easypoi实现简单导出 前言一、easypoi是什么&#xff1f;二、使用步骤 1.传送门2.前端vue3.后端springboot 3.1编写实体类&#xff08;我这里是dto,也一样&#xff09;3.2控制层结尾 前言 今天玩了一下springboot利用easypoi实现excel的导出&#xff0c;以前…

Milvus attu - docker 使用 及 版本兼容

文章目录 版本查看attu 和 milvus 的兼容性Docker 加载attu docker 合并到 Milvus文件管理使用 docker compose 挂在 Milvus,登录 attu 出现报错: Error: Failed to connect to Milvus: Error: 1 CANCELLED: Call cancelled 于是检查兼容问题 版本查看 Milvus 版本发布: htt…

洛谷 P1957 口算练习题 C语言

题目&#xff1a; https://www.luogu.com.cn/problem/P1957 题目描述 王老师正在教简单算术运算。细心的王老师收集了 ii 道学生经常做错的口算题&#xff0c;并且想整理编写成一份练习。 编排这些题目是一件繁琐的事情&#xff0c;为此他想用计算机程序来提高工作效率。王老…

el-select 修改样式

这样漂亮的页面&#xff0c;搭配的却是一个白色风格的下拉框 &#xff0c;这也过于刺眼。。。 调整后样式为&#xff1a; 灯红酒绿总有人看着眼杂&#xff0c;但将风格统一终究是上上选择。下面来处理这个问题。 分为两部分。 第一部分&#xff1a;是修改触发框的样式 第二部…

Proteus中添加新元件库

手上村&#xff1a;本来打算在Proteus中设计充电电路&#xff0c;发现软件自带的元器件库中没有我想要充电芯片。因此&#xff0c;看了其他大神的导入新的元器件步骤&#xff0c;建立自己的元器件库&#xff01;自己也来记录一波&#xff01;话不多说&#xff0c;赶紧上菜&…

数字IC前端学习笔记:脉动阵列的设计方法学(以串行FIR滤波器为例)

相关阅读数字IC前端_日晨难再的博客-CSDN博客https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 引言 脉动结构&#xff08;也称为脉动阵列&#xff09;表示一种有节奏地计算并通过系统传输数据的处理单元(PEs)网络。这些处理单元有规律地…

springboot mvn 打包,jar和资源文件分离打包

默认打包方式如下&#xff1a; <build><finalName>${project.artifactId}</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><execution…

5G CPE核心器件-基带处理器(三)

5G CPE 核心器件 -5G基带芯片 基带芯片简介基带芯片组成与结构技术特点与发展趋势5G基带芯片是5G CPE中最核心的组件,负责接入5G网络,并进行上下行数据业务传输。移动通信从1G发展到5G,终端形态产生了极大的变化,在集成度、功耗、性能等方面都取得巨大的提升。 基带芯片简…

【JavaWeb后端学习笔记】SpringBoot框架下Http请求参数接收

Http请求参数接收 1、简单参数2、实体参数3、数组参数4、集合参数5、日期参数6、Json格式参数&#xff08;常用&#xff09;7、路径参数&#xff08;常用&#xff09;8、接收请求参数常用的几个注解 Http请求能携带各种格式的请求参数。因此也就需要不同的接收方式。 1、简单参…

在 MacOS 上为 LM Studio 更换镜像源

在 MacOS 之中使用 LM Studio 部署本地 LLM时&#xff0c;用户可能会遇到无法下载模型的问题。 一般的解决方法是在 huggingface.co 或者国内的镜像站 hf-mirror.com 的项目介绍卡页面下载模型后拖入 LM Studio 的模型文件夹。这样无法利用 LM Studio 本身的搜索功能。 本文将…

Vue工程化开发中各文件的作用

1.main.js文件 main.js文件的主要作用&#xff1a;导入App.vue&#xff0c;基于App.vue创建结构渲染index.html。

Grule前端表单post后端执行grule引擎规则

Grule前端表单post后端执行grule引擎规则 编写前端表单和后端接口 编写test.go执行grule引擎规则 示例都是 go test 执行的测试代码&#xff0c;所以将里面的测试代码去除 由于之前 NumberExponentExample_test.go 已经验证可运行, 所以将 err 的异常处理去除 package mai…

Android hid 数据传输(device 端 )

最近一直在处理hid 数据需求&#xff0c;简而言之就是两台设备直接可以通过usb 线互相传递数据。 项目架构 为什么Device 端要采用HID&#xff08;人机接口设备&#xff09;的方式发送和接收数据呢&#xff1f; 主要是速度快&#xff0c;举个例子&#xff0c;就是鼠标移动&am…

【Unity基础】Unity中Transform.forward的详解与应用

在Unity中&#xff0c;Transform.forward 是一个常用属性&#xff0c;它表示物体的“前方”方向&#xff0c;即物体本地坐标系中 Z 轴&#xff08;蓝色轴&#xff09;在世界坐标系中的方向。它动态反映物体的旋转情况&#xff0c;非常适合用于移动、检测、方向控制等场景。 什么…

基于 RWKV 的视觉语言模型 VisualRWKV 被 COLING 2025 接收!

基于 RWKV 的视觉语言模型 VisualRWKV 被 COLING 2025 接收&#xff01; COLING&#xff0c;国际计算语言学会议&#xff08;International Conference on Computational Linguistics&#xff09;&#xff0c;是自然语言处理和计算语言学领域的顶级国际会议&#xff08;CCF 推…