python排序算法及优化学习笔记1

简介: python实现的简单的排序算法,以及算法优化,学习笔记1

1.排序算法

1.1冒泡排序

1.1.1算法描述(摘自网络)

原始算法:

1.        比较相邻的元素。如果第一个比第二个大,就交换它们两个;

2.        对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;

3.        针对所有的元素重复以上的步骤,除了最后一个;

4.        重复步骤1~3,直到排序完成。

算法优化:

每一轮步骤1~3排序结束后,如果没有进行排序操作,则表示整个数组已经满足了升序或者降序的顺序,不需要继续排序了,此时退出循环排序,节省时间。

1.1.2算法实现

输入:

Src:一个数组

Order0是降序,1是升序

Opt:默认为True,使用优化算法,False为原始排序算法

@time_count

def bubble(src: list, order=1, opt=True):    

   # src: list

   # order: 0 descend, 1 ascend

   # opt: True optimize, False not optimize

   # print(src)    

   dst = src.copy()

   step = 0

   for i in range(len(dst)-1, 0, -1):

       sorted = not opt

       for j in range(i):

           step += 1

           if (order and dst[j] > dst[j+1]) or (not order and dst[j] < dst[j+1]):

               temp = dst[j]

               dst[j] = dst[j+1]

               dst[j+1] = temp

               sorted = True

       if not sorted:

           print('no need to sort')

           break

   print('step', step)

   return dst

1.2选择排序

1.2.1算法描述(摘自网络)

原始算法:

1.        在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

2.        从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

3.        重复第二步,直到所有元素均排序完毕。

算法优化:

1.        步骤1同时找出最大和最小值,找出的最大和最小值分别存放在各自的序列中,排序完成后输出两个序列的组合。

2.        如果最大值和最小值是同一个值,说明剩下的所有数据都是相同的,可直接退出排序。

1.2.2算法实现

原始算法:

@time_count

def select_origin(src: list, order=1):

   # src: list

   # order: 0 descend, 1 ascend

   # print(src)

   dst_temp = src.copy()

   dst = []

   while len(dst_temp):

       max_id = 0

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

           if dst_temp[i] > dst_temp[max_id]:

               max_id = i

       if order == 0:

           dst.append(dst_temp[max_id])

       else:

           dst.insert(0, dst_temp[max_id])

       dst_temp.pop(max_id)

   return dst

优化算法:

@time_count

def select_opt(src: list, order=1):

   # src: list

   # order: 0 descend, 1 ascend

   # print(src)

   dst_temp = src.copy()

   dst_min = []

   dst_max = []

   while len(dst_temp):

       max_id = 0

       min_id = 0

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

           if dst_temp[i] > dst_temp[max_id]:

               max_id = i

           if dst_temp[i] < dst_temp[min_id]:

               min_id = i

       if max_id == min_id:

           if order == 0:

               dst_max += dst_temp

           else:

               dst_max = dst_temp + dst_max

           break

       if order == 0:

           dst_max.append(dst_temp[max_id])

           dst_min.insert(0,dst_temp[min_id])

       else:

           dst_max.insert(0, dst_temp[max_id])

           dst_min.append(dst_temp[min_id])

       if max_id > min_id:

           dst_temp.pop(max_id)

           dst_temp.pop(min_id)

       elif max_id < min_id:

           dst_temp.pop(min_id)

           dst_temp.pop(max_id)

       else:

           dst_temp.pop(min_id)

   if order == 0:

       return dst_max + dst_min

   else:

       return dst_min + dst_max

1.3插入排序

1.3.1算法描述(摘自网络)

原始算法:

1.        把待排序的数组分成已排序和未排序两部分,初始的时候把第一个元素认为是已排好序的。

2.        从第二个元素开始,在已排好序的子数组中寻找到该元素合适的位置并插入该位置。

3.        重复上述过程直到最后一个元素被插入有序子数组中。

算法优化1

在步骤2中,计算待插入的值靠近序列的开头还是末尾,靠近哪一侧,就从该侧寻找位置插入,减少循环查找的次数。

算法优化2

在步骤2中,计算待插入的值靠近序列的开头、中间还是末尾,,靠近哪一侧,就从该侧寻找位置插入,进一步减少循环查找的次数。

1.3.2算法实现

原始算法:

@time_count

def insert_origin(src: list, order=1):

   # src: list

   # order: 0 descend, 1 ascend

   # print(src)

   dst = src[0:1]

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

       inserted = False

       for j in range(len(dst)):

           if (order and src[i] < dst[j]) or (not order and src[i] > dst[j]):

               dst.insert(j, src[i])

               inserted = True

               break

       if not inserted:

           dst.append(src[i])

   return dst

优化算法1

@time_count

def insert_opt1(src: list, order=1):

   # src: list

   # order: 0 descend, 1 ascend

   # print(src)

   dst = src[0:1]

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

       inserted = False

       if abs(src[i]-dst[0]) <= abs(src[i]-dst[-1]):

           for j in range(len(dst)):

               if (order and src[i] < dst[j]) or (not order and src[i] > dst[j]):

                   dst.insert(j, src[i])

                   inserted = True

                   break

           if not inserted:

               dst.append(src[i])

       else:

           for j in range(len(dst)-1,-1,-1):

               if (order and src[i] > dst[j]) or (not order and src[i] < dst[j]):

                   dst.insert(j+1, src[i])

                   inserted = True

                   break

           if not inserted:

               dst.insert(0,src[i])

   return dst

优化算法2

@time_count

def insert_opt2(src: list, order=1):

   # src: list

   # order: 0 descend, 1 ascend

   # print(src)

   dst = src[0:1]

   def insert_left(src_vlaue, from_mid=False):

       inserted = False

       start = 0 if not from_mid else int(len(dst)/2)

       for j in range(start, len(dst)):

           if (order and src_vlaue < dst[j]) or (not order and src_vlaue > dst[j]):

               dst.insert(j, src_vlaue)

               inserted = True

               break

       if not inserted:

           dst.append(src_vlaue)

   def insert_right(src_vlaue, from_mid=False):

       inserted = False

       start = len(dst)-1 if not from_mid else int(len(dst)/2)

       for j in range(start,-1,-1):

           if (order and src_vlaue > dst[j]) or (not order and src_vlaue < dst[j]):

               dst.insert(j+1, src_vlaue)

               inserted = True

               break

       if not inserted:

           dst.insert(0, src_vlaue)

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

       l = abs(src[i]-dst[0])

       r = abs(src[i]-dst[-1])      

       m = src[i]-dst[int(len(dst)/2)]            

       if l <= abs(m) and l <= r:

           insert_left(src[i])

       elif r <= abs(m) and r <= l:

           insert_right(src[i])

       else:

           if m >= 0:

               insert_left(src[i], True)

           else:

               insert_right(src[i], True)

   return dst

2.算法比较

2.1算法有效性

为证明算法能有效进行排序,使用的数组为:

data0 = [0, 7, 7, -2, 1, -7, 7, 7, 6, -2, 0, 10, 9, 9, 4, 2, 6, 5, 1, 8, 3, 1, 10, 7, -1]

分别使用各个算法进行升序和降序。

1)冒泡排序:

>>> bubble(data0)

no need to sort

step 297

cost 1

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

>>> bubble(data0, 0)

no need to sort

step 297

cost 1

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

>>> bubble(data0,opt=False)

step 300

cost 2

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

>>> bubble(data0, 0, opt=False)

step 300

cost 2

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

2)选择排序

>>> select_opt(data0)

cost 0

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

>>> select_opt(data0,0)

cost 0

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

>>> select_origin(data0)

cost 0

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

>>> select_origin(data0,0)

cost 0

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

>>>

3)插入排序

>>> insert_opt1(data0)

cost 0

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

>>> insert_opt1(data0, 0)

cost 0

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

>>> insert_origin(data0)

cost 0

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

>>> insert_origin(data0, 0)

cost 0

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

>>> insert_opt2(data0)

cost 0

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

>>> insert_opt2(data0, 0)

cost 0

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

>>>

2.2算法比较

使用三组数据比较各个算法的计算时长。

数组1长度为1万,其数值为0~100的随机数。

数组2长度为10万,其数值为0~100的随机数。

数组3长度为1万,其数值前50000~100的随机数,后5000为升序的值。

import random

import datetime

 

data1 = [random.randint(-100,100) for i in range(10000)]

data2 = [random.randint(-100,100) for i in range(100000)]

data3 = [random.randint(-100,100) for i in range(5000)] + [i for i in range(5000)]

使用datetime计算算法执行的时长。

def time_count(func):

   def wrapper(*args, **kwargs):

       start = datetime.datetime.now()

       result = func(*args, **kwargs)

       print('cost', int((datetime.datetime.now() - start).total_seconds()*1000))

       return result

   return wrapper

每个算法,对同一组数据,计算5次升序,取平均值,单位是ms,结果如下:

算法

冒泡排序

选择排序

插入排序

原始

优化

提升

原始

优化

提升

原始

优化1

优化2

提升1

提升2

数据11w

降序

11998

11976

0.19%

3498

3146

10.08%

2323

1178

281

49.28%

87.89%

升序

11760

11765

-0.05%

3517

3143

10.63%

2278

1169

527

48.66%

76.84%

数据210w

降序

1263493

1263487

0.00%

351886

316437

10.07%

230149

119339

28089

48.15%

87.80%

升序

1251652

1251670

0.00%

354900

315789

11.02%

234406

118856

53412

49.29%

77.21%

数据31w

降序

15113

15112

0.01%

3671

3209

12.58%

593

324

91

45.38%

84.65%

升序

8693

6665

23.32%

3688

3203

13.14%

3917

308

145

92.15%

96.30%

备注:提升=(原始-优化)/原始*100%

1.png

1 数据1降序排序各算法耗时

2.png

2 数据1升序排序各算法耗时

结论:

1、原始算法排序效率:插入排序>选择排序>冒泡排序。

2、冒泡排序,对于乱序的数据1和数据2,优化算法与原始算法用时接近,无优化效果,对特殊顺序的数组3,升序的优化算法有明显的提升,降序也无优化效果。

3、选择排序和插入排序的优化算法对各组数据均能生效。

4、选择排序的优化算法对各组数据的均提升约10%

5、插入排序的优化效果相比于其他两个算法的优化效果提升最大。

6、插入排序的效率:优化算法2>优化算法1>原始算法。

说明:以上实验并未严格控制测试环境,数据仅供参考。

 

目录
相关文章
|
21天前
|
机器学习/深度学习 算法
基于遗传优化ELM网络的时间序列预测算法matlab仿真
本项目实现了一种基于遗传算法优化的极限学习机(GA-ELM)网络时间序列预测方法。通过对比传统ELM与GA-ELM,验证了参数优化对非线性时间序列预测精度的提升效果。核心程序利用MATLAB 2022A完成,采用遗传算法全局搜索最优权重与偏置,结合ELM快速训练特性,显著提高模型稳定性与准确性。实验结果展示了GA-ELM在复杂数据中的优越表现,误差明显降低。此方法适用于金融、气象等领域的时间序列预测任务。
|
21天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于PSO粒子群优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM
本项目基于MATLAB2022a/2024b开发,结合粒子群优化(PSO)算法与双向长短期记忆网络(BiLSTM),用于优化序列预测任务中的模型参数。核心代码包含详细中文注释及操作视频,涵盖遗传算法优化过程、BiLSTM网络构建、训练及预测分析。通过PSO优化BiLSTM的超参数(如学习率、隐藏层神经元数等),显著提升模型捕捉长期依赖关系和上下文信息的能力,适用于气象、交通流量等场景。附有运行效果图预览,展示适应度值、RMSE变化及预测结果对比,验证方法有效性。
|
23天前
|
机器学习/深度学习 边缘计算 算法
NOMA和OFDMA优化算法分析
NOMA和OFDMA优化算法分析
49 6
|
23天前
|
监控 大数据 API
Python 技术员实践指南:从项目落地到技术优化
本内容涵盖Python开发的实战项目、技术攻关与工程化实践,包括自动化脚本(日志分析系统)和Web后端(轻量化API服务)两大项目类型。通过使用正则表达式、Flask框架等技术,解决日志分析效率低与API服务性能优化等问题。同时深入探讨内存泄漏排查、CPU瓶颈优化,并提供团队协作规范与代码审查流程。延伸至AI、大数据及DevOps领域,如商品推荐系统、PySpark数据处理和Airflow任务编排,助力开发者全面提升从编码到架构的能力,积累高并发与大数据场景下的实战经验。
Python 技术员实践指南:从项目落地到技术优化
|
26天前
|
算法
基于遗传优化算法的带时间窗多车辆路线规划matlab仿真
本程序基于遗传优化算法,实现带时间窗的多车辆路线规划,并通过MATLAB2022A仿真展示结果。输入节点坐标与时间窗信息后,算法输出最优路径规划方案。示例结果包含4条路线,覆盖所有节点并满足时间窗约束。核心代码包括初始化、适应度计算、交叉变异及局部搜索等环节,确保解的质量与可行性。遗传算法通过模拟自然进化过程,逐步优化种群个体,有效解决复杂约束条件下的路径规划问题。
|
29天前
|
机器学习/深度学习 数据采集 算法
基于GWO灰狼优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM
本项目基于Matlab 2022a/2024b实现,结合灰狼优化(GWO)算法与双向长短期记忆网络(BiLSTM),用于序列预测任务。核心代码包含数据预处理、种群初始化、适应度计算及参数优化等步骤,完整版附带中文注释与操作视频。BiLSTM通过前向与后向处理捕捉序列上下文信息,GWO优化其参数以提升预测性能。效果图展示训练过程与预测结果,适用于气象、交通等领域。LSTM结构含输入门、遗忘门与输出门,解决传统RNN梯度问题,而BiLSTM进一步增强上下文理解能力。
|
1月前
|
机器学习/深度学习 算法 数据挖掘
基于WOA鲸鱼优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM
本项目基于MATLAB 2022a/2024b实现,采用WOA优化的BiLSTM算法进行序列预测。核心代码包含完整中文注释与操作视频,展示从参数优化到模型训练、预测的全流程。BiLSTM通过前向与后向LSTM结合,有效捕捉序列前后文信息,解决传统RNN梯度消失问题。WOA优化超参数(如学习率、隐藏层神经元数),提升模型性能,避免局部最优解。附有运行效果图预览,最终输出预测值与实际值对比,RMSE评估精度。适合研究时序数据分析与深度学习优化的开发者参考。
|
1月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于GA遗传优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM
本内容包含基于BiLSTM与遗传算法(GA)的算法介绍及实现。算法通过MATLAB2022a/2024b运行,核心为优化BiLSTM超参数(如学习率、神经元数量),提升预测性能。LSTM解决传统RNN梯度问题,捕捉长期依赖;BiLSTM双向处理序列,融合前文后文信息,适合全局信息任务。附完整代码(含注释)、操作视频及无水印运行效果预览,适用于股票预测等场景,精度优于单向LSTM。
|
9月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
272 3
|
12月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【7月更文挑战第22天】在大数据领域,Python算法效率至关重要。本文深入解析时间与空间复杂度,用大O表示法衡量执行时间和存储需求。通过冒泡排序(O(n^2)时间,O(1)空间)与快速排序(平均O(n log n)时间,O(log n)空间)实例,展示Python代码实现与复杂度分析。策略包括算法适配、分治法应用及空间换取时间优化。掌握这些,可提升大数据处理能力,持续学习实践是关键。
249 1

热门文章

最新文章

推荐镜像

更多