list 排序_十个必知的排序算法|Python实例系列

十大排序:

1.冒泡排序2.选择排序3.插入排序4.希尔排序5.归并排序6.快速排序7.堆排序8.计数排序9.桶排序10.基数排序

78d0f9bfed7a183de1429d60973d3d5a.png

完整代码和注释如下

# -*- coding: UTF-8 -*-#Space: https://github.com/Tri-x/exercise#Space: https://space.bilibili.com/187492698#Author: Trix#Description: 十大经典排序算法#Python的排序算法用的是Tim Sort 一种源自归并排序和插入排序的稳定高效的排序算法 也许以后会单独做一期视频来介绍该算法#也许以后会做一期视频来介绍一些奇葩的排序算法 比如 睡眠排序、猴子排序、面条排序、珠排序from random import randint#随机整数from time import process_time#计时nums_lists=[[]for n in range(4)]#随机创建四个无序数列 用来粗略地测试每种排序算法的用时for n in range(500):#数列长度为500nums_lists[0].append(randint(-400,400))#随机范围(-400,400)for n in range(1000):nums_lists[1].append(randint(-8000,8000))for n in range(5001):nums_lists[2].append(randint(-2000,2000))for n in range(10000):nums_lists[3].append(randint(-9000,9000))#由于创建的随机数列太长,就不打印排序前和排序后的结果了def bubble_sort(num_list):#冒泡排序 该算法名字的由来是因为越小的值会慢慢"浮"到数列的顶端#循环遍历数列,一次比较两个相邻的值,如果后者值大于前者值,就把他们的位置互相交换for n in range(len(num_list)-1):#因为最后一次已经顺序正确了所以循环次数-1for m in range(len(num_list)-1-n):#循环每结束一次 这一次循环中最大的值会移动到上一次循环中最大值的前一位 数列中后面的值已经有序 所以次数-nif num_list[m]>num_list[m+1]:#大小比较num_list[m+1],num_list[m]=num_list[m],num_list[m+1]#位置交换return num_listdef select_sort(num_list):#选择排序 选择最小值#每次循环在数列中找到最小值,放到上一次循环找到的最小值的后一位,第一次放在首位for n in range(len(num_list)-1):#因为最后一次已经顺序正确了所以循环次数-1min_index=n#设最小值为索引为n的值for m in range(n,len(num_list)):#n值前已完成排序if num_list[m]=1:#控制步长范围#以下为插入排序的内容 并对插入排序进行了改进for n in range(gap,len(num_list)):while (n-gap)>=0:#控制比较范围if num_list[n]基准值,exchange_index不变,exchange_index仍为0n=3时,扫描值6>基准值,exchange_index不变,exchange_index仍为0n=4时,扫描值3每个左右子节点的完全二叉树#这样每次构建后索引[0]为最大值,在第n次结束,就把[0]和[-n]位置互换 在[0:-n-1]的范围内进行下次的完全二叉树构建list_len=len(num_list)#获取数列长度for n in range(list_len//2,-1,-1):#list_len//2为父节点索引的规律 //表示除法向下取整 n∈[list_len//2,-1),n∈Z range(start,stop,step) step为-1时为从后往前遍历heapify(num_list,list_len,n)#数列完全二叉树的初始化 构建每个父节点>每个左右子节点的完全二叉树for n in range(list_len-1,0,-1):#n∈[list_len-1,0),n∈Znum_list[0],num_list[n]=num_list[n],num_list[0]#对上一次构建完成的二叉树 首尾值互换list_len-=1#限定这一次构造完全二叉树的范围heapify(num_list,list_len,0)#由于已经初始化完成 可以直接从首项开始 在不包含上次最大值的范围内进行构造完全二叉树return num_listdef heapify(num_list,list_len,parent_index):#构建父节点>左右子节点的完全二叉树#第n排有n^(n-1),从左到右填充数值,可以得到父节点索引和左右子节点索引的规律left_index=2*parent_index+1#对于每个父节点索引 左节点索引的规律right_index=left_index+1#对于每个父节点索引 右节点索引的规律max_index=parent_index#假设父节点比左右子节点值都大 默认最大值的索引为父节点索引if left_indexnum_list[max_index]:#如果在列表范围内 左节点值>父节点值max_index=left_index#父节点和左节点的索引互换if right_indexnum_list[max_index]:#右节点同理max_index=right_indexif max_index!=parent_index:#如果现在的父节点索引不等于一开始的假设的最大值的索引 说明父节点和它的某一节点需要互换索引值num_list[parent_index],num_list[max_index]=num_list[max_index],num_list[parent_index]heapify(num_list,list_len,max_index)#递归构建整个数列的完全二叉树def count_sort(num_list):#计数排序 数数#找出数列中最大值和最小值 创建min~max这么多个0用来统计数列中每个值出现的次数,再从最小值依次排放到最大值max_num=max(num_list)#找到最大值min_num=min(num_list)#找到最小值neg_list=[]#负数数列pos_list=[]#非负数数列for num in num_list:#对负数和非负数分别处理if num<0:neg_list.append(num)#向负数数列添加负数if num>=0:pos_list.append(num)#向非负数数列添加非负数if len(neg_list)!=0:#如果有负数neg_counts_list=[0 for n in range(min_num,0)]#创建最小值这么多个0来累计每个负数出现的次数for n in range(len(neg_list)):#对于负数数列中的每个值neg_counts_list[neg_list[n]]+=1neg_index=0#初始排序索引为0for n in range(-len(neg_counts_list),0):#对于计数列表中的每一项while neg_counts_list[n]>0:#不为0就说明有计数 为0说明没有计数neg_list[neg_index]=n#依次排放数值neg_index+=1#每次排放后index+1neg_counts_list[n]-=1#每次排放后数值所对应的计数-1if len(pos_list)!=0:#如果有非负数pos_counts_list=[0 for n in range(max_num+1)]#创建max+1这么多个0来累计每个非负数出现的次数 因为是以每个值为索引 所以要max+1个0for n in range(len(pos_list)):#对于数列中的每个非负值pos_counts_list[pos_list[n]]+=1#计数列表索引和数列的值一一对应pos_index=0#初始排序索引为0for n in range(len(pos_counts_list)):#对于计数列表中的每一项while pos_counts_list[n]>0:#不为0就说明有计数 为0说明没有计数pos_list[pos_index]=n#依次排放数值pos_index+=1#每次排放后index+1pos_counts_list[n]-=1#每次排放后数值所对应的计数-1result_list=neg_list+pos_list#负数数列和非负数数列结合return result_listdef bucket_sort(num_list):#桶排序 计数排序的改进版#找出数列中最大值和最小值 创建min~max这么多个桶用来统计数列中每个值出现的次数,再从第一个桶倾倒到最后一个桶bucket_list=[0 for n in range(max(num_list)-min(num_list)+1)]#创建min~max这么多个桶for n in range(len(num_list)):#对于当前值bucket_list[num_list[n]-min(num_list)]+=1#添加到值对应的桶内 即对应桶计数+1result_list=[]#结果列表for n in range(len(bucket_list)):#对于每个桶if bucket_list[n]!=0:#如果桶内有数result_list+=[n+min(num_list)]*bucket_list[n]#直接把桶里的所有数倒出来return result_listdef radix_sort(num_list):#基数排序 比较位数上的值#比较每一位上的数字大小 当每一位比较完成排序也就完成pos_list=[]#负数数列neg_list=[]#非负数数列for num in num_list:#对负数和非负数分别处理if num<0:neg_list.append(num)if num>=0:pos_list.append(num)if len(neg_list)!=0:#如果有负数neg_num_digit=0#初始位数while neg_num_digit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值