排序与查找算法详解

1.排序

1.1 算法的稳定性

排序 :将一组数据,按照某种规则进行排列的操作

排序算法:实现排序操作的过程描述

算法的稳定性 :具有相同关键字的记录排序后其相对位置保持不变,这样的算法是稳定性算法

1.2 交换排序

交换排序:根据序列中两个元素关键字的比较结果来交换各自的位置

交换排序主要有:冒泡排序和快速排序

1.2.1 冒泡排序

冒泡排序 :从末尾开始,重复访问要排序的元素列表(含 n 个元素),依次比较相邻的两个元素,如果逆序(如:从大到小,从z-a),就交换它们的位置,这样一趟下来就将当前最小元素冒泡到第一位了;这样重复 n-1 趟,最终完成元素列表排序

注意:如果从前往后开始,则是每轮沉淀当前最大值元素

代码实现如下:

复制代码
#1.定义函数 bubble_sort(list)
def bubble_sort(list):
    for i in range(len(list)-1):
        flag = True                  #若发生交换则为False
        for j in range(len(list)-1-i):
            if list[j] > list[j+1]:  #若前一个数大于后一个数则交换
                list[j], list[j+1] = list[j+1], list[j]
                flag = False         #发生交换
        if flag == True:           #若未发生交换则说明列表已有序,提前退出
            break
    return list

#2.测试函数
if __name__ == '__main__':
    list = [3,2,1,5,4,6]
    print(bubble_sort(list))

1.冒泡排序是一种稳定的排序算法

  • 最坏时间复杂度:
  • 最优时间复杂度:

1.3 选择排序

选择排序 :第一次从待排序的序列中选择最小(或最大)的一个元素放在序列的起始位置,然后从剩余的未排序元素中继续寻找最小(或最大)元素,放到已排序的序列末尾,以此类推,知道全部有序

代码实现如下:

复制代码
#1.定义函数 select_sort(list)
def select_sort(list):
    for i in range(len(list)-1):
        min_index = i               #记录本轮最小值元素的索引
        for j in range(i+1, len(list)):
            if list[j] < list[min_index]:
                min_index = j
        list[i], list[min_index] = list[min_index], list[i]
    return list
#2.测试函数
if __name__ == '__main__':
    list = [3,2,1,5,4,6]
    print(select_sort(list))

选择排序是一种不稳定的排序算法

  • 最坏时间复杂度:
  • 最坏时间复杂度:

1.4 插入排序

插入排序 :每次将一个待排序记录按其关键字大小插入到前面已经排好序的子序列,直到全部记录插入完成

代码实现如下:

复制代码
#1.定义 insert_sort(list)函数
def insert_sort(list):
    for i in range(1, len(list)):
        key = list[i]
        j = i-1
        while j >=0 and key < list[j]:
            list[j+1] = list[j]
            j -= 1
        list[j+1] = key
    return list
#2.测试函数
if __name__ == '__main__':
    list = [3,2,1,5,4,6,7]
    print(insert_sort(list))

插入排序是一种稳定的排序算法

  • 最坏时间复杂度:
  • 最优时间复杂度:

适用条件 :如果已经有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这时就可以用插入排序算法,算法适用于少量数据的排序

2.查找

2.1 二分查找

二分查找 :又叫折半查找;将有序序列(假设升序)分为3部分,依次是中值前,中值,中值后;将要查找的值与中值进行比较,若小于中值则在中值前查找,若大于中值则在中值后查找,若等于中值直接返回

时间复杂度 :

2.1.1 递归实现

代码实现如下:

复制代码
#1.递归实现:定义 binary_search(list)函数
def binary_search(list, item, offset=0): #offset记录当前切片在原始数组的起点下标
    if len(list) == 0:      #递归退出条件1
        return None
    mid = len(list)//2
    if list[mid] == item:   #递归退出条件2
        return offset + mid
    elif item < list[mid]:
        return binary_search(list[:mid], item, offset)
    else:
        return binary_search(list[mid+1:], item, offset + mid + 1)
    return None            #走到这步说明没有找到,返回False
#2.函数测试
list = [0, 1, 2, 8, 13, 17, 19, 32, 42]
print(binary_search(list, 13))
  • 最坏空间复杂度:
  • 最优空间复杂度:

2.1.2 非递归实现

复制代码
#1.定义 binary_search(list)函数
def binary_search(list, item):
    low = 0                #初始化low
    high = len(list) - 1   #初始化high
    while low <= high:
        mid = (low + high) // 2
        if item == list[mid]:
            return mid
        if item < list[mid]:
            high = mid - 1
        else:
            low = mid + 1
    return None

#2.测试函数
if __name__ == '__main__':
    list = [1, 2, 3, 4, 5, 6, 7, 8, 9,10]
    print(binary_search(list, 0))
相关推荐
云和数据.ChenGuang6 分钟前
Python 常见特殊方法详解:__new__、__init__、__del__、__str__、__repr__ 与 __getattribute__
开发语言·人工智能·python·1024程序员节
xyouyuweizhu27 分钟前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
迪菲赫尔曼30 分钟前
【基础篇 04】第一次使用终端:命令在哪里输入,电脑现在又“站”在哪里?
python·yolo·目标检测
qianbo_insist1 小时前
# 在 Qwen3.5-2B 上把 GDN-1 无损换成 GDN-2:一次完整的架构手术实验(负结果)
人工智能·pytorch·python·架构
多弗朗皮卡丘1 小时前
C++的IO流
开发语言·c++·io流·文件io流
骑着蜗牛撵大象3271 小时前
AI Agent 工程化开发实战(三):用 StateGraph 给智能体搭一条可回放的状态流水线
java·开发语言·jvm·ai·状态管理·langgraph·stategraph
itmigrate2 小时前
Rust 里的所有权误区:不是不写 clone 就叫高性能
开发语言·后端·rust
Brilliantwxx2 小时前
【Linux】 文件访问与路径解析:目录、文件名、dentry、路径缓冲与 dcache 全解析
linux·运维·服务器·开发语言·spring
摇滚侠2 小时前
《On Java 中文版 基础卷》阅读笔记 初始化和清理 08
java·开发语言·笔记
xiangyun612 小时前
C++ 手撕 shared_ptr:引用计数与控制块到底长什么样?
开发语言·c++·算法·面试·stl