在路上---学习篇(一)Python 数据结构和算法 (4) --希尔排序、归并排序
独白:
希尔排序是经过优化的插入排序算法,之前所学的排序在空间上都是使用列表本身。而归并排序是利用增加新的空间,来换取时间复杂度的减少。这俩者理念完全不一样,注定造成的所消耗的时间不同以及空间上的不同。
归并排序涉及到递归的使用,需要理解其中精髓才能更好了解归并排序,以及其他应用到递归的算法。理解其本质才能更好的应用。
希尔排序
希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
时间复杂度
- 最优时间复杂度:根据步长序列的不同而不同
- 最坏时间复杂度:O(n2)
- 稳定想:不稳定
"""
希尔排序
最优时间复杂度: 根据步长序列不同而不同
最坏时间复杂度: O(n*n)
稳定性 : 不稳定
""" import time
import random def shell_sort(list):
n = len(list)
#初始步长
gap = n // 2
while gap > 0:
# 按初始步长进行插入排序
for j in range(gap, n):
i = j
# 插入排序
while i >= gap and list[i-gap] > list[i]:
list[i-gap], list[i] = list[i], list[i-gap]
i -= gap # 得到新的步长
gap = gap // 2 def new_num(lis):
"""随机生成50个数加入列表中"""
for i in range(50):
j = random.randint(0, 10000)
lis.append(j) if __name__ == '__main__':
first_time = time.time()
# 空列表
lis = [54,26,93,17,77,31] # 随机函数添加到列表中
# new_num(lis)
print(lis) # 列表排序
shell_sort(lis)
print(lis) # 结束时间
last_time = time.time() print("共用时%s" % (last_time - first_time))
归并排序
归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
时间复杂度
- 最优时间复杂度:O(nlogn)
- 最坏时间复杂度:O(nlogn)
- 稳定性:稳定
"""
归并排序
最优时间复杂度:O(nlogn)
最坏时间复杂度:O(nlogn)
稳定性:稳定 与其他排序区别
利用一个新列表讲算法排序后的元素储存当中
空间换时间
""" import time
import random def merge_sort(list):
"""归并排序"""
n = len(list)
if n <= 1:
return list
# 最大整除
mid = n // 2
# left 利用递归 截取的列表形成的有序列表
left_list = merge_sort(list[:mid])
# right 利用递归 截取的列表形成的有序列表
right_list =merge_sort(list[mid:])
# 创建 左右游标记录列表值的索引
left_pointer, right_pointer = 0,0
# 创建新空列表
result = []
# 循环 比较数值大小
# 退出循环条件 当左右游标其中一个等于所在列表的长度时
while left_pointer < len(left_list) and right_pointer < len(right_list):
# 判断 左值和右值大小
if left_list[left_pointer] <= right_list[right_pointer]:
result.append(left_list[left_pointer])
# 每判断一次 游标加一
left_pointer += 1
else:
result.append(right_list[right_pointer])
right_pointer += 1
# 将最后一个数值加入新列表中
result += left_list[left_pointer:]
result += right_list[right_pointer:]
# 返回值
return result def new_num(lis):
"""随机生成50个数加入列表中"""
for i in range(50):
j = random.randint(0, 100)
lis.append(j) if __name__ == '__main__':
first_time = time.time()
# 空列表
lis = [] # 随机函数添加到列表中
new_num(lis)
print(lis) # 列表排序
# 因为归并排序最后是返回一个新列表,所以打印输出为新列表
alist = merge_sort(lis)
print(alist) # 结束时间
last_time = time.time() print("共用时%s" % (last_time - first_time))
在路上---学习篇(一)Python 数据结构和算法 (4) --希尔排序、归并排序的更多相关文章
- Java数据结构和算法(五)--希尔排序和快速排序
在前面复习了三个简单排序Java数据结构和算法(三)--三大排序--冒泡.选择.插入排序,属于算法的基础,但是效率是偏低的,所以现在 学习高级排序 插入排序存在的问题: 插入排序在逻辑把数据分为两部分 ...
- Python数据结构与算法_删除排序数组中的重复项(06)
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成. ...
- 【数据结构与算法】希尔排序 python和c++实现
算法思路 每一次:固定间隔把数据分组,每一组进行排序 每次比上次选取更小的间隔分组,再每组排序,直到间隔为1 代码 c++:(越看越不明白了,后看) int gap = length;//length ...
- python数据结构与算法
最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...
- Python数据结构与算法--List和Dictionaries
Lists 当实现 list 的数据结构的时候Python 的设计者有很多的选择. 每一个选择都有可能影响着 list 操作执行的快慢. 当然他们也试图优化一些不常见的操作. 但是当权衡的时候,它们还 ...
- Python数据结构与算法--算法分析
在计算机科学中,算法分析(Analysis of algorithm)是分析执行一个给定算法需要消耗的计算资源数量(例如计算时间,存储器使用等)的过程.算法的效率或复杂度在理论上表示为一个函数.其定义 ...
- Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- Python数据结构与算法之图的广度优先与深度优先搜索算法示例
本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...
- Python数据结构与算法设计总结篇
1.Python数据结构篇 数据结构篇主要是阅读[Problem Solving with Python]( http://interactivepython.org/courselib/static ...
- Python数据结构与算法设计(总结篇)
的确,正如偶像Bruce Eckel所说,"Life is short, you need Python"! 如果你正在考虑学Java还是Python的话,那就别想了,选Pytho ...
随机推荐
- linux 配置dns及代理
简介 对于新装的环境,可能无法访问外网,此时需要设置代理或DNS实现访问. 类似wget.yum.pip这类命令都需要通过网络进行下载. 配置dns服务 在/etc/resolv.conf中添加如下两 ...
- npm install 下载依赖的过程
首先检查.npmrc文件,项目级.npmrc文件>用户级的.npmrc文件>全局性的.npmrc文件>npm内置的.npmrc文件 是否有lock文件 没有lock文件 从npm远程 ...
- vite — 超快且方便的编译工具
我们编写的代码,比如 ES6. TypeScript.react 等是不能被浏览器直接识别的,需要通过 webpack .rollup 这样的构建工具来对代码进行转换.编译. 但随着项目越来越大,需要 ...
- nodejs中事件循环机制与面试题详解
nodejs中架构如下图所示,通过v8引擎来执行js代码,通过中间层 libuv 来读写文件系统.网络等做一些操作. nodejs中提供阻塞和非阻塞的调用方式,比如fs模块中读取文件,可以根据 ...
- CAP 7.2 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 7.2 版本正式版,我们在这个版本中主要致力于 Dashboard 对 k8s 服务发现的支持. 从 7.1 版本以来,我们发布了4个小版本,在这些版本中我们 ...
- 终于搞懂了python2和python3的encode(编码)与decode(解码)
终于搞懂了python2的编码 在python2下碰到非常多次的中文乱码,这次来梳理一下编码问题. 在python 2中默认编码是 ASCII,而在python 3中默认编码是 unicode. un ...
- MIT6.s081/6.828 lectrue4:page tables 以及 Lab3 心得
不管是计算机组成还是操作系统,虚拟内存都是其中的重要内容,所以这一节我会结合 CSAPP 第九章:虚拟内存 来一起复习(顺便一说,CSAPP 这一节的 lab 是要求设计一个内存分配器,也是很有意思的 ...
- 使用MediatR和FluentValidation实现CQRS应用程序的数据验证
本文将重点介绍如何通过MediatR的管道功能将FluentValidation集成到项目中实现验证功能. 什么是CQRS? CQRS(Command Query Responsibility Seg ...
- 利用CI机制管控jar依赖树
1. 现状·问题 你还记得你排查jar冲突的付出么? 为了有效控制jar包更新带来的未知jar引入和变动,我们经常使用dependency-tree来查看依赖关系排查问题,通常是出现问题再被动分析和排 ...
- Linux查看磁盘空间,文件系统、挂载
Linux磁盘空间,文件系统.挂载 概述 在使用以下命令查看磁盘使用情况时 df -h du -sh 目标路径 作为初级开发者,Linux入门级选手,可能不禁要问Linux系统的文件系统跟window ...