浅谈排序算法与优化(仅部分,Updating)

浅谈排序算法与优化(仅部分,Updating)

欢迎查阅与star的源码
写在最前面,此文章少了各排序算法的对比,但多了一份由浅入深的理解,以及代码、及算法的优化的思路
阅读文章约 需 5min

列表排序

排序

将一组“无序”的记录序列调整为“有序”的记录序列

列表排序

将无序的列表变为有序列表

输入:列表;

输出:有序列表

升序与降序

内置排序函数:sort(),基于timsort排序算法

Timsort是一种混合稳定排序算法,源自归并排序(merge sort)和插入排序(insertion sort)

有兴趣的伙计可以看看这两篇文章

sort算法运用原理1

sort算法运用原理2

TimSort

常见排序算法
LOW:

冒泡:

列表每两个相邻的数,如果前面比后面大,则交换这两个数

一趟排序完成后,则无序区减少一个数,有序区增加一个数

@cal_time
def bubble_sort(li: List[List]) -> List:
print('初始列表', li)
print('初始列表长度:', len(li))
for i in range(len(li) - 1):  # 第i躺,总次数
i += 1
for j in range(len(li) - i - 1):  # 指针
   if li[j] > li[j + 1]:  # 如果指针所对应的值大于对比的值,则二者交换位置
       li[j], li[j + 1] = li[j + 1], li[j]
   else:
       break
print(f'冒泡排序第{i}次', li)


li = [np.random.randint(0, 1000) for i in range(5)]
bubble_sort(li)


数据来源于numpy.randmo.randint()随机取数,运行流程:
冒泡排序第1[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第2[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第3[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第4[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第5[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第6[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第7[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第8[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]
冒泡排序第9[257, 620, 136, 379, 392, 118, 312, 892, 647, 655]

# 排序次数:列表长度-1,
# 缘由将无序区转化为有序区:(再看一遍以下这段代码, 如果li[j]>li[j+1],则二者交换位置)
if li[j] > li[j + 1]: 
    li[j], li[j + 1] = li[j + 1], li[j]

# 当一维数组长度为10000的时候所需时间为:

Runtime

优化:

在一次回头看看冒泡排序具体实现思路,将列表每两个相邻的数,如果前面比后面大,则交换这两个数,一趟排序完成后,则无序区减少一个数,有序区增加一个数

如果无序区已经是有序的呢?按照代码执行流程可知,

如果前者比后者大,那么则两个交换位置。(假设为降序,前面为无序区,后面为有序区)

否则不执行任何交换操作,但会执行便利(也可以理解为此运算"不执行任何交换操作,无实际意义")

优化目标:(将“不执行任何交换的操作去掉”),咱们在回头看看,具体实际的运算是在第二层for循环里面的,也就说所谓的“无用功”也是在这里产生的

无用功体现为:无论是否进行了位置交换,都会在往有序区在遍历检查一遍

思路如下:

主要优化的地方在跳出循环,在它不交换位置的时候,直接跳出此次的循环

假设它全部都是有序的,并设个标记True,

当如果循环内发生了位置交换,则改变标记为False。

流程控制,if。当if True的时则会执行if内部代码(设立return,或者break)主要跳出循环。避免对有序区进行有一次的排序操作

具体代码实现如下:

def bubble_sort(li: List):
    print("The len of List:", len(li))  # 输入数组长度
    for i in range(len(li) - 1):  # 保证输入的数组在计算范围类,此处的“-1”是因为索引=长度-1
        flag = True
        for j in range(len(li) - i - 1):
            if li[j] > li[j + 1]:
                li[j + 1], li[j] = li[j], li[j + 1]
                flag = False
            print("Sorting times:%d, Status:%s" % (i + 1, li))
        if flag:
            break

选择:

插入:

Stronger

快速排序:

堆排序

归并排序

其他排序:

希尔排序

计数排序

基数排序

   break

选择:

插入:

Stronger

快速排序:

堆排序

归并排序

其他排序:

希尔排序

计数排序

基数排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值