[Python]算法之排序

1 算法的稳定性

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

2 排序

排序:使一串记录,按照其中的某个或某些关键字的大小递增递减

排序算法:使记录递增递减的方法

不稳定的排序算法:选择排序、快速排序、希尔排序、堆排序

稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序

3 冒泡排序O(n2)

每次把最大的泡泡筛选出来的过程,实现思路:相邻的元素,两两比较,直到循环结束,得到第一个最大值;依次类推,直到得出所有的最大值,完成排序。

外层循环控制排序的总轮数=>len(容器)-1

内层循环主要控制两两元素比较次数

# 冒泡排序
def bubble_sort(num_list):
    n=len(num_list)
    # 循环n-1次
    for i in range(n-1,0,-1):
        for j in range(i):
            if num_list[j]>num_list[j+1]:
                num_list[j],num_list[j+1]=num_list[j+1],num_list[j]
    return num_list

if __name__=='__main__':
    num_list=[4,1,3,1,5,2]
    print(bubble_sort(num_list))

# 冒泡排序优化
def bubble_sort(num_list):
    n=len(num_list)
    for i in range(n-1,0,-1):
        # 添加一个标记,代表是否有元素交换
        flag=False
        for j in range(i):
            if num_list[j]>num_list[j+1]:
                num_list[j],num_list[j+1]=num_list[j+1],num_list[j]
                flag=True
        # 如果flag为False,则表示排序完成,可退出循环
        if not flag:
            break
    return num_list

if __name__=='__main__':
    num_list=[4,1,3,1,5,2]
    print(bubble_sort(num_list))

4 选择排序(n2)

# 选择排序
def selection_sort(num_list):
    n = len(num_list)
    for i in range(n - 1):
        min_index = i
        for j in range(i + 1, n):
            if num_list[j] < num_list[min_index]:
                min_index = j
        if min_index != i:
            num_list[i], num_list[min_index] = num_list[min_index], num_list[i]

    return num_list


if __name__ == '__main__':
    num_list = [4, 1, 3, 1, 5, 2]
    print(selection_sort(num_list))

5 插入排序(n2)

排序算法:插入排序【图解+代码】_哔哩哔哩_bilibili

# 插入排序
def insert_sort(num_list):
    n=len(num_list)
    for i in range(1,n):
        # 待插入的数
        key=num_list[i]
        # 从待插入数的前一个数开始比较
        j=i-1
        # 循环比较待插入数之前的数字,只要比待插入的数字大
        while j>=0 and num_list[j]>key:
            # 就向右移动,给待插入的数字让位
            num_list[j+1]=num_list[j]
            j-=1
        # 找到前面没有比待插入的数大为止,把待插入的数放入数列
        # 因为上一步j-1,所以待插入的下标为j+1
        num_list[j+1]=key
    return num_list

num_list = [6, 8, 4, 5, 1, 1, 5, 2, 6]
sorted_list = insert_sort(num_list)
print(sorted_list)

6 希尔排序O(n log n)

数据结构——三分钟搞定希尔排序_哔哩哔哩_bilibili

[算法]六分钟彻底弄懂希尔排序,简单易懂_哔哩哔哩_bilibili

# 希尔排序
def shell_sort(num_list):
    # 初始间隔为列表长度的一半
    gap = len(num_list) // 2
    # 间隔为0作为循环结束条件
    while gap > 0:
        # 从gap开始,对每一个元素进行插入排序
        for i in range(gap,len(num_list)):
            # 待插入值
            key=num_list[i]
            j=i
            # 循环比较待插入数之前的数字,只要比待插入的数字大
            while j>=gap and num_list[j-gap]>key:
                # 就向右移动,给待插入的数字让位
                num_list[j]=num_list[j-gap]
                j-=gap
            # 找到合适的位置后,插入当前元素
            num_list[j]=key
        
        # 减小间隔
        gap//=2
    return num_list

num_list = [6, 8, 4, 5, 1, 1, 5, 2, 6]
sorted_list = shell_sort(num_list)
print(sorted_list)       

7 归并排序O(n log n)

排序算法:归并排序【图解+代码】_哔哩哔哩_bilibili

数据结构——三分钟搞定归并排序_哔哩哔哩_bilibili

# 归并排序
def merge_sort(num_list):
    # 如果数组长度小于等于1,则直接返回
    if len(num_list)<=1:
        return num_list
    # 找到数组的中间点
    mid=len(num_list)//2
    # 递归地对左边边进行归并排序
    left_half=merge_sort(num_list[:mid])
    # 递归地对右半边进行归并排序
    right_half=merge_sort(num_list[mid:])
    # 合并已排序的左右两部分
    return merge(left_half,right_half)

def merge(left,right):
    # 初始化结果数组
    merged=[]
    # 初始化两个指针,分别指向左半部分和右半部分起始位置
    left_index=0
    right_index=0
    
    # 合并两个数组
    while left_index<len(left) and right_index<len(right):
        # 比较左半部分和右半部分当前元素
            # 如果左半部分的元素小于等于右半部分的元素,添加左半部分的元素到结果组
            if left[left_index]<=right[right_index]:
                merged.append(left[left_index])
                left_index+=1
            else:
            # 如果右半部分的元素小于等于左半部分的元素,添加右半部分的元素到结果组
                merged.append(right[right_index])
                right_index+=1
    # 将剩余的元素添加到结果数组(如果有)
    merged.extend(left[left_index:])
    merged.extend(right[right_index:])
    
    return merged

num_list = [6, 8, 4, 5, 1, 1, 5, 2, 6]
sorted_list = merge_sort(num_list)
print(sorted_list)

8 快速排序O(n log n)

不稳定

【快速排序之父】当哲学家决定去当程序员_哔哩哔哩_bilibili

全网最清晰快速排序,看完快排思想和代码全部通透,不通透你打我!_哔哩哔哩_bilibili

# 快速排序
def quick_sort(num_list):
    # 如果数组长度小于等于1,直接返回
    if len(num_list) <= 1:
        return num_list

    # 选择一个基准元素,通常选择第一个元素
    pivot = num_list[0]

    # 划分数组为三个部分:小于基准的部分、等于基准的部分、大于基准的部分
    less = [i for i in num_list[1:] if i < pivot]
    equal = [i for i in num_list if i == pivot]
    greater = [i for i in num_list[1:] if i > pivot]

    # 递归地对小于和大于部分进行快速排序,并将结果拼接起来
    return quick_sort(less) + equal + quick_sort(greater)

num_list = [6, 8, 4, 5, 1, 1, 5, 2, 6]
sorted_list = quick_sort(num_list)
print(sorted_list)

9 堆排序O(n log n)

堆排序(heapsort)_哔哩哔哩_bilibili

堆的特点:①完全二叉树②父节点大于子节点

10 计数排序O(n + k)

计数排序_哔哩哔哩_bilibili

11 桶排序O(n + k)

12 基数排序O(n + k)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值