10种排序算法(Python实现)

冒泡排序

1、 两重循环,每次都将一个点移动到最终位置

  1. def BubbleSort(lst):
  2. n=len(lst)
  3. if n<=1:
  4. return lst
  5. for i in range (0,n):
  6. for j in range(0,n-i-1): # 每轮确定一个点的最终位置
  7. if lst[j]>lst[j+1]:
  8. (lst[j],lst[j+1])=(lst[j+1],lst[j])
  9. return lst
  10. x=input("请输入待排序数列:\n")
  11. y=x.split()
  12. arr=[]
  13. for i in y:
  14. arr.append(int(i))
  15. arr=BubbleSort(arr)
  16. #print(arr)
  17. print("数列按序排列如下:")
  18. for i in arr:
  19. print(i,end=' ')

快速排序

快排具体算法执行流程如下:https://www.cnblogs.com/MOBIN/p/4681369.html

1、每次都会确定基准值的最终位置

2、快排使用到了,分页和递归

  1. def QuickSort(lst):
  2. # 此函数完成分区操作,并且返回该元素的最终位置
  3. def partition(arr, left, right):
  4. # 执行快排的过程
  5. key = left # 使用第一个数为基准数
  6. while left < right:
  7. # 如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现
  8. while left < right and arr[right] >= arr[key]:
  9. right -= 1
  10. # 如果列表前边的数,比基准数小或相等,则后移一位直到有比基准数大的数出现
  11. while left < right and arr[left] <= arr[key]:
  12. left += 1
  13. # 此时已找到一个比基准大的书,和一个比基准小的数,将他们互换位置
  14. (arr[left], arr[right]) = (arr[right], arr[left])
  15. # 当从两边分别逼近,直到两个位置相等时结束,将左边小的同基准进行交换
  16. (arr[left], arr[key]) = (arr[key], arr[left])
  17. # 返回目前基准所在位置的索引
  18. return left
  19. def quicksort(arr, left, right):
  20. if left >= right:
  21. return
  22. # 获取一个元素的最终位置
  23. mid = partition(arr, left, right)
  24. # 递归调用
  25. # print(arr)
  26. quicksort(arr, left, mid - 1)
  27. quicksort(arr, mid + 1, right)
  28. # 主函数
  29. n = len(lst)
  30. if n <= 1:
  31. return lst
  32. quicksort(lst, 0, n - 1)
  33. return lst
  34. print("<<< Quick Sort >>>")
  35. x = input("请输入待排序数列:\n")
  36. y = x.split()
  37. arr = []
  38. for i in y:
  39. arr.append(int(i))
  40. arr = QuickSort(arr)
  41. # print(arr)
  42. print("数列按序排列如下:")
  43. for i in arr:
  44. print(i, end=' ')

插入排序(有序+无序)

插入排序算法流程:1 从第二个元素开始,第一个默认为有序,将取出的元素放到前面有序的队列中,放的时候是平移。n2时间复杂度。注意这里比较的时候顺便挪动,因此是两重循环

  1. def InsertSort(lst):
  2. n=len(lst)
  3. if n<=1:
  4. return lst
  5. for i in range(1,n):
  6. j=i
  7. target=lst[i] #每次循环的一个待插入的数
  8. while j>0 and target<lst[j-1]: #比较、后移,给target腾位置
  9. lst[j]=lst[j-1]
  10. j=j-1
  11. lst[j]=target #把target插到空位
  12. return lst
  13. x=input("请输入待排序数列:\n")
  14. y=x.split()
  15. arr=[]
  16. for i in y:
  17. arr.append(int(i))
  18. arr=InsertSort(arr)
  19. #print(arr)
  20. print("数列按序排列如下:")
  21. for i in arr:
  22. print(i,end=' ')

希尔排序

希尔排序的算法流程:

第一遍:分成5组,

第二遍:分成2组,4 3 5 8 5会被进行插入排序

第三遍:gap=1,分成1组,对全部数组进行直接插入排序

  1. def shell_sort(arr):
  2. # 初始化间隔gap
  3. gap = len(arr) // 2
  4. # 开始希尔排序
  5. while gap > 0:
  6. # 遍历所有间隔为gap的元素组
  7. for i in range(gap, len(arr)):
  8. temp = arr[i]
  9. j = i
  10. # 插入排序的思想,对间隔为gap的元素组进行直接插入排序操作
  11. while j - gap >= 0 and temp < arr[j - gap]:
  12. arr[j] = arr[j - gap]
  13. j -= gap
  14. arr[j] = temp
  15. # 更新间隔
  16. gap //= 2
  17. return arr
  18. # 测试希尔排序函数
  19. example_array = [64, 34, 25, 12, 22, 11, 90]
  20. sorted_array = shell_sort(example_array)
  21. print("排序后的数组:", sorted_array)

堆排序(难)

堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆这种数据结构的特性来进行排序。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。

堆排序算法包括两个主要步骤:

建立堆:将无序数组构造成一个最大堆或最小堆。

逐步提取堆顶元素并恢复堆性质:将堆顶元素与最后一个元素交换,然后减少堆的大小,最后调整剩余元素构成的堆,重复这个过程直到堆的大小为1。

  1. def heapify(arr, n, i):
  2. # 设定最大值索引为i
  3. largest = i
  4. # 左子节点索引为2*i+1
  5. left = 2 * i + 1
  6. # 右子节点索引为2*i+2
  7. right = 2 * i + 2
  8. # 如果左子节点大于根节点
  9. if left < n and arr[i] < arr[left]:
  10. largest = left
  11. # 如果右子节点比最大值还大
  12. if right < n and arr[largest] < arr[right]:
  13. largest = right
  14. # 如果最大值不是根节点
  15. if largest != i:
  16. arr[i], arr[largest] = arr[largest], arr[i] # 交换
  17. # 递归地定义子堆
  18. heapify(arr, n, largest)
  19. def heap_sort(arr):
  20. n = len(arr)
  21. # 构建最大堆
  22. for i in range(n // 2 - 1, -1, -1):
  23. heapify(arr, n, i)
  24. # 一个个从堆顶取出元素
  25. for i in range(n - 1, 0, -1):
  26. arr[i], arr[0] = arr[0], arr[i] # 交换
  27. heapify(arr, i, 0)
  28. return arr
  29. # 测试堆排序函数
  30. example_array = [12, 11, 13, 5, 6, 7]
  31. sorted_array = heap_sort(example_array)
  32. print("排序后的数组:", sorted_array)

归并排序(合并有序序列)

O(nlogn)的时间复杂度,稳定排序

  • 把长度为n的输入序列分成两个长度为n/2的子序列;
  • 对这两个子序列分别采用归并排序;
  • 将两个排序好的子序列合并成一个最终的排序序列(这里一次遍历就行了,合并两个有序序列的复杂度是n)
  1. def MergeSort(lst):
  2. #合并左右子序列函数
  3. def merge(arr,left,mid,right):
  4. temp=[] #中间数组
  5. i=left #左段子序列起始
  6. j=mid+1 #右段子序列起始
  7. while i<=mid and j<=right:
  8. if arr[i]<=arr[j]:
  9. temp.append(arr[i])
  10. i+=1
  11. else:
  12. temp.append(arr[j])
  13. j+=1
  14. while i<=mid:
  15. temp.append(arr[i])
  16. i+=1
  17. while j<=right:
  18. temp.append(arr[j])
  19. j+=1
  20. for i in range(left,right+1): # !注意这里,不能直接arr=temp,他俩大小都不一定一样
  21. arr[i]=temp[i-left]
  22. #递归调用归并排序
  23. def mSort(arr,left,right):
  24. if left>=right:
  25. return
  26. mid=(left+right)//2
  27. mSort(arr,left,mid)
  28. mSort(arr,mid+1,right)
  29. merge(arr,left,mid,right)
  30. n=len(lst)
  31. if n<=1:
  32. return lst
  33. mSort(lst,0,n-1)
  34. return lst
  35. x=input("请输入待排序数列:\n")
  36. y=x.split()
  37. arr=[]
  38. for i in y:
  39. arr.append(int(i))
  40. arr=MergeSort(arr)
  41. #print(arr)
  42. print("数列按序排列如下:")
  43. for i in arr:
  44. print(i,end=' ')

计数排序(空间浪费严重)

  • 找出待排序的数组中最大和最小的元素;(来建立一个桶)如果这里最大值100,就有100个桶
  • 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
  • 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
  • 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
  1. def CountSort(lst):
  2. n=len(lst)
  3. num=max(lst)
  4. count=[0]*(num+1)
  5. for i in range(0,n):
  6. count[lst[i]]+=1
  7. arr=[]
  8. for i in range(0,num+1):
  9. for j in range(0,count[i]):
  10. arr.append(i)
  11. return arr
  12. x=input("请输入待排序数列:\n")
  13. y=x.split()
  14. arr=[]
  15. for i in y:
  16. arr.append(int(i))
  17. arr=CountSort(arr)
  18. #print(arr)
  19. print("数列按序排列如下:")
  20. for i in arr:
  21. print(i,end=' ')

桶排序(合并多个有序数组)

1、 先分多个桶(可以直接使用n/10这种方法,桶是有序的)

2、在桶内进行排序(任何排序均可)

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. //微信公众号:bigsai
  4. public class test3 {
  5. public static void main(String[] args) {
  6. int a[]= {1,8,7,44,42,46,38,34,33,17,15,16,27,28,24};
  7. List[] buckets=new ArrayList[5];
  8. for(int i=0;i<buckets.length;i++)//初始化
  9. {
  10. buckets[i]=new ArrayList<Integer>();
  11. }
  12. for(int i=0;i<a.length;i++)//将待排序序列放入对应桶中
  13. {
  14. int index=a[i]/10;//对应的桶号
  15. buckets[index].add(a[i]);
  16. }
  17. for(int i=0;i<buckets.length;i++)//每个桶内进行排序(使用系统自带快排)
  18. {
  19. buckets[i].sort(null);
  20. for(int j=0;j<buckets[i].size();j++)//顺便打印输出
  21. {
  22. System.out.print(buckets[i].get(j)+" ");
  23. }
  24. }
  25. }
  26. }

基数排序(Radix Sort)(多轮桶排)

基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前

算法实现:

1、取最大值得到最高位

2、从低位到高位,建立桶依次收集和分散,反复几轮之后就是有序的了

算法图解:

下面这段代码实现的很巧妙

1、取最大值得到最高位

2、从低位到高位,建立桶依次收集和分散,反复几轮之后就是有序的了


  1. def radix(arr):
  2. digit = 0
  3. max_digit = 1
  4. max_value = max(arr)
  5. #找出列表中最大的位数 10^max_digit
  6. while 10**max_digit < max_value:
  7. max_digit = max_digit + 1
  8. while digit < max_digit:
  9. temp = [[] for i in range(10)] # 二维数组,有10个元素 [[],[],[],..[]]
  10. for i in arr:
  11. #求出每一个元素的个、十、百位的值
  12. t = int((i/(10**digit))%10) # 依次取个位 10位 百位
  13. temp[t].append(i)
  14. coll = []
  15. # 将桶里的东西依次倒出来
  16. for bucket in temp:
  17. for i in bucket:
  18. coll.append(i)
  19. arr = coll # 此时coll其实已经排过序了
  20. digit = digit + 1
  21. return arr

选择排序(有序+无序)

选择排序(select sorting)也是一种简单的排序方法。

基本思想为:

第一次从 arr[0]~arr[n-1] 中选取最小值,与 arr[0] 交换

第二次从 arr[1]~arr[n-1] 中选取最小值,与 arr[1] 交换

第 i 次从 arr[i-1]~arr[n-1] 中选取最小值,与 arr[i-1] 交换

依次类图,总共通过 n - 1 次,得到一个按排序码从小到大排列的有序序列

  1. def selection_sort(arr):
  2. # 遍历数组中的所有元素
  3. for i in range(len(arr)):
  4. # 将当前位置设为最小值位置
  5. min_index = i
  6. # 从i+1到数组末尾中找到最小元素的索引
  7. for j in range(i + 1, len(arr)):
  8. if arr[j] < arr[min_index]:
  9. min_index = j
  10. # 将找到的最小值交换到它应该在的位置
  11. arr[i], arr[min_index] = arr[min_index], arr[i]
  12. return arr
  13. # 测试选择排序函数
  14. example_array = [64, 25, 12, 22, 11]
  15. sorted_array = selection_sort(example_array)
  16. print("排序后的数组:", sorted_array)

总结

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。

不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面



参考文档

1、https://www.cnblogs.com/onepixel/p/7674659.html

11种排序算法(Python实现)的更多相关文章

  1. 三种排序算法python源码——冒泡排序、插入排序、选择排序

    最近在学习python,用python实现几个简单的排序算法,一方面巩固一下数据结构的知识,另一方面加深一下python的简单语法. 冒泡排序算法的思路是对任意两个相邻的数据进行比较,每次将最小和最大 ...

  2. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  3. 排序算法 python实现

    一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序的稳定性: 经过某种排序后,如果两 ...

  4. C#常用8种排序算法实现以及原理简介

    public static class SortExtention { #region 冒泡排序 /* * 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先比较a[1]与a[2 ...

  5. 十大经典排序算法(Python,Java实现)

    参照:https://www.cnblogs.com/wuxinyan/p/8615127.html https://www.cnblogs.com/onepixel/articles/7674659 ...

  6. 史上最全单链表的增删改查反转等操作汇总以及5种排序算法(C语言)

    目录 1.准备工作 2.创建链表 3.打印链表 4.在元素后面插入元素 5.在元素前面增加元素 6.删除链表元素,要注意删除链表尾还是链表头 7.根据传入的数值查询链表 8.修改链表元素 9.求链表长 ...

  7. JavaScript实现的7种排序算法

    所谓排序算法,即通过特定的算法因式将一组或多组数据按照既定模式进行重新排序.这种新序列遵循着一定的规则,体现出一定的规律,因此,经处理后的数据便于筛选和计算,大大提高了计算效率.对于排序,我们首先要求 ...

  8. 秒杀9种排序算法(JavaScript版)

    一:你必须知道的 1> JS原型 2> 排序中的有序区和无序区 3> 二叉树的基本知识 如果你不知道上面三个东西,还是去复习一下吧,否则,看下面的东西有点吃力. 二:封装丑陋的原型方 ...

  9. PHP的几种排序算法的比较

    这里列出了几种PHP的排序算法的时间比较的结果,,希望对大家有所帮助 /* * php 四种排序算法的时间与内置的sort排序比较 * 3000个元素,四种算法的排序所用的时间比较 * 冒泡排序 85 ...

  10. 常见排序算法-Python实现

    常见排序算法-Python实现 python 排序 算法 1.二分法     python    32行 right = length-  :  ]   ):  test_list = [,,,,,, ...

随机推荐

  1. burp suite历程-安装burp suite

    安装时,捯饬了快一上午,不是jdk高了就是装上后不好使了,后来看了下以下文章,安装成功,特此记录以备不时之需: 内容拷贝至链接:https://juejin.cn/post/6844904111867 ...

  2. clearValidate()和resetFields()表单校验的用法和区别

    目标:实现表单重置和清除验证 1.整个表单的校验移除 <Form ref="form" rule={this.rules}> <FormItem prop=&qu ...

  3. vue使用 elementUI中el-upload的遇到的问题总结

    使用场景,使用el-upload上传文件,选择文件后不立即上传到服务器上,点击提交按钮时与其他form表单数据一起提交,类似的需求,相信有很多小伙伴遇到,可能也会遇到跟我一起的问题,在这里记录一下 & ...

  4. Django框架——模版层之标签、自定义过滤器 标签及inclusion_tag(了解)、模版的继承与导入、模型层之前期准备、ORM常用关键字

    模版层之标签 {% if 条件1(可以自己写也可以用传递过来的数据) %} <p>今天又是周三了</p> {% elif 条件2(可以自己写也可以用传递过来的数据) %} &l ...

  5. mysql入门操作(部分操作,不为完全格式)

    查询数据库在电脑中绝对路径: show variables like '%datadir%'; 设置字符集 set names gbk; 导入数据库 source 绝对路径 eg: source D: ...

  6. 力扣1083(MySQL)-销售分析Ⅲ(简单)

    题目: Table: Product Table: Sales 编写一个SQL查询,报告2019年春季才售出的产品.即仅在2019-01-01至2019-03-31(含)之间出售的商品. 以 任意顺序 ...

  7. 力扣388(java)-文件的最长绝对路径(中等)

    题目: 假设有一个同时存储文件和目录的文件系统.下图展示了文件系统的一个示例: 这里将 dir 作为根目录中的唯一目录.dir 包含两个子目录 subdir1 和 subdir2 .subdir1 包 ...

  8. 全链路灰度新功能:MSE 上线配置标签推送

    简介: 本文介绍了全链路灰度场景给配置管理带来的问题,介绍了 MSE 针对这一场景的解决方案,并通过实践的方式展示了配置标签推送的使用流程.后续,MSE 还会针对配置治理做更多的探索,帮助用户更好地解 ...

  9. DE10-Lite锁相环使用教程

    DE10-Lite锁相环使用教程 目标:本文讲述如何在Quartus里设置和例化一个锁相环. 引言 锁相环(PLL)是一种闭环频率控制电路,用于比较压控振荡器的输入信号和输出信号之间的相位差. 负反馈 ...

  10. Oracle、达梦:同一数据库边查询边插入的两种方式

    1.方式1 插入的表需要构建好 -- 建表:6秒 500毫秒:抽数据100万:10秒 640毫秒.11秒 189毫秒 insert into T_HUGE_COMPRESS (ID, NAME) ( ...