一,希尔排序(shell sort)

希尔排序其实是由插入排序演变过来的,是插入排序的一种更高效的改进版本。希尔排序是不稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的

1,插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
2,但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位

算法原理

希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

例如有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10

然后我们对每列进行排序:

10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45

将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45

排序之后变为:

10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94

最后以1步长进行排序(此时就是简单的插入排序了)。

基于python的程序代码(折半)

import randomshell_list = [random.randint(i, i * 7 + 8) for i in range(11)]
random.shuffle(shell_list)
print('未排序>>>:', shell_list)
n = len(shell_list)
gap = n // 2
while gap >= 1:for i in range(gap, n):while i > 0 and shell_list[i] < shell_list[i-gap]:shell_list[i], shell_list[i-gap] = shell_list[i-gap], shell_list[i]i -= gapgap //= 2print('已排序>>>:', shell_list)

基于python的程序代码(Knuth序列)

Knuth 间隔序列 3*h+1,即1, 4,13, 40, 121…

# knuth序列
import randomshell_list = [random.randint(i, i * 7 + 8) for i in range(11)]
random.shuffle(shell_list)
print('未排序>>>:', shell_list)
n = len(shell_list)
gap = 0
while gap <= n // 3:gap = gap * 3 + 1
while gap >= 1:for i in range(gap, n):while i > 0 and shell_list[i] < shell_list[i-gap]:shell_list[i], shell_list[i-gap] = shell_list[i-gap], shell_list[i]i -= gapgap //= 3print('已排序>>>:', shell_list)

复杂度:

希尔排序的平均时间复杂度约为O(n^1.3)
最坏时间复杂度为O(n^2)
最好时间复杂度为O(n)
空间复杂度为O(1)

二,归并排序(merge sort)

归并排序,是建立在归并操作上的一种有效的排序算法。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。

采用分治法:

分割:递归地把当前序列平均分割成两半。
整合:在保持元素顺序的同时将上一步得到的子序列整合到一起(归并)。

归并操作:

归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。


基于python的程序代码

import randomdef merge_sort(merge_list):# 求列表长度n = len(merge_list)if n == 1:  # 当长度为1时,说明不能再分割return merge_listmiddle_num = n // 2  # 找到中间元素left_list = merge_sort(merge_list[:middle_num])  # 左边通过归并排序后形成新的有序的新列表right_list = merge_sort(merge_list[middle_num:])  # 右边通过归并排序后形成新的有序的新列表# 将两个有序的子序列合并为一个新的有序序列left_pointer, right_pointer = 0, 0  # 定义左右两个起始指针new_list = []while left_pointer < len(left_list) and right_pointer < len(right_list):  # 只要左右两个指针有一个到达尾部,循环便结束if left_list[left_pointer] < right_list[right_pointer]:  # 左边比右边小时,将左边数小的元素追加到新的空列表中new_list.append(left_list[left_pointer])left_pointer += 1  # 左边指针位置加一else:new_list.append(right_list[right_pointer])  # 右边比左边小时或左右相等时,将右边的元素追加到新的列表中right_pointer += 1  # 右边的指针位置加一# 当左右任意一边指针到达尾部时,就将另一边剩余的所有元素直接追加到新列表中。new_list += left_list[left_pointer:]new_list += right_list[right_pointer:]return new_listif __name__ == '__main__':merge_list = [random.randint(i, i * 7 + 8) for i in range(21)]random.shuffle(merge_list)print('未排序>>>:', merge_list)merge_list = merge_sort(merge_list)print('已排序>>>:', merge_list)

复杂度:

归并排序的平均时间复杂度,最坏时间复杂度和最好时间复杂度都为O(n*log n),空间复杂度是O(n)。(注:此处的对数函数是n倍以2为底n的对数)

归并排序是稳定的

三,快速排序

快速排序,又称分区交换排序(partition-exchange sort),简称快排,最早由东尼·霍尔提出。在平均状况下,排序n个项目要O(nlog n)次比较。在最坏状况下则需要O(n^2)次比较,但这种状况并不常见。事实上,快速排序O(nlog n)通常明显比其他算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地达成。(注:此处的对数函数是n倍以2为底n的对数)

算法原理

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。

步骤为:

挑选基准值:从数列中挑出一个元素,称为“基准”(pivot),
分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成。
递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。


基于python的程序代码

import randomdef pivot_sort(quick_list, left, right):pivot_number = quick_list[left]  # 选择第一个元素为轴元素while left < right:  # 假如left=right,说明要排序的列表只有一个元素;left<right说明要排序的列表长度大于等于2;while left < right and quick_list[right] >= pivot_number:  # 在保证列表长度大于2的情况下,如果右边的元素大于轴元素right -= 1  # 就让右边的指针往左边移一步else:  # 假如右边的元素小于轴元素(也可省略,但下面的语句要向前缩进四个空格)quick_list[left] = quick_list[right]  # 就把右边的元素移到左边的空位置上while left < right and quick_list[left] <= pivot_number:  # 在保证列表长度为2的情况下,假如左边的元素小于轴元素,left += 1  # 就让左边的指针像右移动一步else:  # 假如左边的元素大于轴元素(也可省略,但下面的语句要向前缩进四个空格)quick_list[right] = quick_list[left]  # 就把左边的元素移到右边的空位上quick_list[left] = pivot_number  # 让轴元素归位return left  # 这里返回left或者right都可以,即轴元素归位的索引def quick_sort(quick_list, left, right):if left < right:middle_num = pivot_sort(quick_list, left, right)quick_sort(quick_list, left, middle_num - 1)quick_sort(quick_list, middle_num + 1, right)if __name__ == '__main__':quick_list = [i for i in range(100)]random.shuffle(quick_list)print('\033[31;1m未排序>>>:\033[0m', quick_list)quick_sort(quick_list, 0, len(quick_list) - 1)print('\033[32;1m排序后>>>:\033[0m', quick_list)

复杂度:

快速排序的平均时间复杂度和最好时间复杂度都为O(n*log n),最坏时间复杂度O(n^2),空间复杂度是O(log n)。(注:此处的对数函数是以2为底的)

快速排序是不稳定的

算法是程序的灵魂之快希归相关推荐

  1. md5与des算法有何不同_Python算法详解:为什么说算法是程序的灵魂?

    算法是程序的灵魂,只有掌握了算法,才能轻松地驾驭程序开发.软件开发工作不是按部就班,而是选择一种最合理的算法去实现项目功能.算法能够引导开发者在面对一个项目功能时用什么思路去实现,有了这个思路后,编程 ...

  2. moead算法流程步骤_算法——抓住程序的灵魂

    做任何事情都要有一定的步骤,为了解决一个问题而采取的方法和步骤就称为算法.C语言的算法是计算机算法,即计算机能够执行的算法.只有明确了算法后,才能使应用程序实现某些功能.所以,通常人们会将算法称为程序 ...

  3. 计算机程序的灵魂,算法——抓住程序的灵魂

    做任何事情都要有一定的步骤,为了解决一个问题而采取的方法和步骤就称为算法.C语言的算法是计算机算法,即计算机能够执行的算法.只有明确了算法后,才能使应用程序实现某些功能.所以,通常人们会将算法称为程序 ...

  4. 《C++ 开发从入门到精通》——2.5 算法是程序的灵魂

    本节书摘来自异步社区出版社<C++ 开发从入门到精通>一书中的第2章,第2.5节,作者: 王石磊 , 韩海玲,更多章节内容可以访问云栖社区"异步社区"公众号查看. 2. ...

  5. 开篇词 | 算法是程序的“灵魂”

    大家好,我是王晓华,网名 orbit.2015 年出版了一本书,名为<算法的乐趣>,以"趣味性"为着手点,介绍了二十多个趣味算法的原理和实现,主要目的是希望读者了解到算 ...

  6. 寒假挑战PythonTip(一人一python)总结——算法是程序的灵魂,程序员的心法

    2014年2月中旬,我上升到挑战python英雄榜第3名.这是我寒假修炼算法的成果之一.来一下总结吧! Linux的创始人Linus Torvalds在一次演讲中有一段涉及"什么才是优秀程序 ...

  7. c语言的程序灵魂是什么,C语言 第二章 程序的灵魂--算法

    <C语言 第二章 程序的灵魂--算法>由会员分享,可在线阅读,更多相关<C语言 第二章 程序的灵魂--算法(39页珍藏版)>请在人人文库网上搜索. 1.第二章 程序的灵魂-算法 ...

  8. 《C语言程序设计》(谭浩强第五版) 第2章 算法——程序的灵魂

    <C语言程序设计>(谭浩强第五版) 第2章 算法--程序的灵魂 习题解析与答案 你也可以上程序咖(https://meta.chengxuka.com),打开大学幕题板块,不但有答案,讲解 ...

  9. 第二章:算法——程序的灵魂

    第二章:算法--程序的灵魂 2.1 程序 = 算法 + 数据结构 一个程序主要包括以下两方面的信息: 对数据的描述.在程序中指定用到哪些数据,以及这些数据的类型和数据的组织形式.这就是数据结构. 对操 ...

最新文章

  1. iOS下音视频通信-基于WebRTC
  2. 【实验】DHCP、NAT配置案例
  3. Linux下apache服务器安装,sqlite安装,apache启动,关闭,重启,编写cig程序进行测试,浏览器访问cig程序
  4. 刷爆了!李彦宏:这类程序员我给100万!你怎么看?
  5. 【OpenCV 例程200篇】09. 图像的裁剪(cv2.selectROI)
  6. 信息学奥赛C++语言: 奶牛乘法
  7. 计算机虚拟现实技术论文好写吗,计算机虚拟现实技术论文.docx
  8. 解决 adobe reader 只能翻页,不能滚动的问题
  9. markdown写作技巧
  10. python selenium 刷课_基于Python和selenium的内蒙古继续教育网---刷课
  11. 方差、标准差、协方差
  12. 2022-2028全球姿势矫正器行业调研及趋势分析报告
  13. dcn网络与公网_DCN网络安全分析
  14. 通过Cookie跳过登录验证码
  15. 《Arduino与LabVIEW开发实战》第3章 如何连接Arduino与LabVIEW
  16. netlink编程注意事项
  17. 基于单片机的温度控制系统
  18. 华为OD机试(A、B卷)、机考,200分的题目整理如下,冲满分必备
  19. IntelliJ IDEA 日常使用介绍
  20. hardware 中的几个地址问题

热门文章

  1. ECS_FML——小议高斯分布
  2. python 进程池/线程池
  3. LGame(Android版)开发示例之连连看
  4. 因修改了用户文件夹名而无法使用pip安装python第三方模块的两种实用解决方法
  5. FFmpeg进行笔记本摄像头+麦克风实现流媒体直播服务,展示在浏览器上。
  6. [wp] 攻防世界-wtf.sh-150
  7. 安卓测试工程师必须了解
  8. 微信小程序 满意度调查问卷答题类小程序实现
  9. 玩转Python中迭代器与迭代对象的使用与演示
  10. 我,退休金8000,带孙子6年,退休前是大官,看到儿媳妇对我的称呼后,我直接怒了...