list 排序_十个必知的排序算法|Python实例系列
生活随笔
收集整理的這篇文章主要介紹了
list 排序_十个必知的排序算法|Python实例系列
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
十大排序:
1.冒泡排序2.選擇排序3.插入排序4.希爾排序5.歸并排序6.快速排序7.堆排序8.計數(shù)排序9.桶排序10.基數(shù)排序
完整代碼和注釋如下
# -*- coding: UTF-8 -*-#Space: https://github.com/Tri-x/exercise#Space: https://space.bilibili.com/187492698#Author: Trix#Description: 十大經(jīng)典排序算法#Python的排序算法用的是Tim Sort 一種源自歸并排序和插入排序的穩(wěn)定高效的排序算法 也許以后會單獨做一期視頻來介紹該算法#也許以后會做一期視頻來介紹一些奇葩的排序算法 比如 睡眠排序、猴子排序、面條排序、珠排序from random import randint#隨機整數(shù)from time import process_time#計時nums_lists=[[]for n in range(4)]#隨機創(chuàng)建四個無序數(shù)列 用來粗略地測試每種排序算法的用時for n in range(500):#數(shù)列長度為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))#由于創(chuàng)建的隨機數(shù)列太長,就不打印排序前和排序后的結(jié)果了def bubble_sort(num_list):#冒泡排序 該算法名字的由來是因為越小的值會慢慢"浮"到數(shù)列的頂端#循環(huán)遍歷數(shù)列,一次比較兩個相鄰的值,如果后者值大于前者值,就把他們的位置互相交換for n in range(len(num_list)-1):#因為最后一次已經(jīng)順序正確了所以循環(huán)次數(shù)-1for m in range(len(num_list)-1-n):#循環(huán)每結(jié)束一次 這一次循環(huán)中最大的值會移動到上一次循環(huán)中最大值的前一位 數(shù)列中后面的值已經(jīng)有序 所以次數(shù)-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):#選擇排序 選擇最小值#每次循環(huán)在數(shù)列中找到最小值,放到上一次循環(huán)找到的最小值的后一位,第一次放在首位for n in range(len(num_list)-1):#因為最后一次已經(jīng)順序正確了所以循環(huán)次數(shù)-1min_index=n#設(shè)最小值為索引為n的值for m in range(n,len(num_list)):#n值前已完成排序if num_list[m]=1:#控制步長范圍#以下為插入排序的內(nèi)容 并對插入排序進行了改進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每個左右子節(jié)點的完全二叉樹#這樣每次構(gòu)建后索引[0]為最大值,在第n次結(jié)束,就把[0]和[-n]位置互換 在[0:-n-1]的范圍內(nèi)進行下次的完全二叉樹構(gòu)建list_len=len(num_list)#獲取數(shù)列長度for n in range(list_len//2,-1,-1):#list_len//2為父節(jié)點索引的規(guī)律 //表示除法向下取整 n∈[list_len//2,-1),n∈Z range(start,stop,step) step為-1時為從后往前遍歷heapify(num_list,list_len,n)#數(shù)列完全二叉樹的初始化 構(gòu)建每個父節(jié)點>每個左右子節(jié)點的完全二叉樹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]#對上一次構(gòu)建完成的二叉樹 首尾值互換list_len-=1#限定這一次構(gòu)造完全二叉樹的范圍heapify(num_list,list_len,0)#由于已經(jīng)初始化完成 可以直接從首項開始 在不包含上次最大值的范圍內(nèi)進行構(gòu)造完全二叉樹return num_listdef heapify(num_list,list_len,parent_index):#構(gòu)建父節(jié)點>左右子節(jié)點的完全二叉樹#第n排有n^(n-1),從左到右填充數(shù)值,可以得到父節(jié)點索引和左右子節(jié)點索引的規(guī)律left_index=2*parent_index+1#對于每個父節(jié)點索引 左節(jié)點索引的規(guī)律right_index=left_index+1#對于每個父節(jié)點索引 右節(jié)點索引的規(guī)律max_index=parent_index#假設(shè)父節(jié)點比左右子節(jié)點值都大 默認最大值的索引為父節(jié)點索引if left_indexnum_list[max_index]:#如果在列表范圍內(nèi) 左節(jié)點值>父節(jié)點值max_index=left_index#父節(jié)點和左節(jié)點的索引互換if right_indexnum_list[max_index]:#右節(jié)點同理max_index=right_indexif max_index!=parent_index:#如果現(xiàn)在的父節(jié)點索引不等于一開始的假設(shè)的最大值的索引 說明父節(jié)點和它的某一節(jié)點需要互換索引值num_list[parent_index],num_list[max_index]=num_list[max_index],num_list[parent_index]heapify(num_list,list_len,max_index)#遞歸構(gòu)建整個數(shù)列的完全二叉樹def count_sort(num_list):#計數(shù)排序 數(shù)數(shù)#找出數(shù)列中最大值和最小值 創(chuàng)建min~max這么多個0用來統(tǒng)計數(shù)列中每個值出現(xiàn)的次數(shù),再從最小值依次排放到最大值max_num=max(num_list)#找到最大值min_num=min(num_list)#找到最小值neg_list=[]#負數(shù)數(shù)列pos_list=[]#非負數(shù)數(shù)列for num in num_list:#對負數(shù)和非負數(shù)分別處理if num<0:neg_list.append(num)#向負數(shù)數(shù)列添加負數(shù)if num>=0:pos_list.append(num)#向非負數(shù)數(shù)列添加非負數(shù)if len(neg_list)!=0:#如果有負數(shù)neg_counts_list=[0 for n in range(min_num,0)]#創(chuàng)建最小值這么多個0來累計每個負數(shù)出現(xiàn)的次數(shù)for n in range(len(neg_list)):#對于負數(shù)數(shù)列中的每個值neg_counts_list[neg_list[n]]+=1neg_index=0#初始排序索引為0for n in range(-len(neg_counts_list),0):#對于計數(shù)列表中的每一項while neg_counts_list[n]>0:#不為0就說明有計數(shù) 為0說明沒有計數(shù)neg_list[neg_index]=n#依次排放數(shù)值neg_index+=1#每次排放后index+1neg_counts_list[n]-=1#每次排放后數(shù)值所對應(yīng)的計數(shù)-1if len(pos_list)!=0:#如果有非負數(shù)pos_counts_list=[0 for n in range(max_num+1)]#創(chuàng)建max+1這么多個0來累計每個非負數(shù)出現(xiàn)的次數(shù) 因為是以每個值為索引 所以要max+1個0for n in range(len(pos_list)):#對于數(shù)列中的每個非負值pos_counts_list[pos_list[n]]+=1#計數(shù)列表索引和數(shù)列的值一一對應(yīng)pos_index=0#初始排序索引為0for n in range(len(pos_counts_list)):#對于計數(shù)列表中的每一項while pos_counts_list[n]>0:#不為0就說明有計數(shù) 為0說明沒有計數(shù)pos_list[pos_index]=n#依次排放數(shù)值pos_index+=1#每次排放后index+1pos_counts_list[n]-=1#每次排放后數(shù)值所對應(yīng)的計數(shù)-1result_list=neg_list+pos_list#負數(shù)數(shù)列和非負數(shù)數(shù)列結(jié)合return result_listdef bucket_sort(num_list):#桶排序 計數(shù)排序的改進版#找出數(shù)列中最大值和最小值 創(chuàng)建min~max這么多個桶用來統(tǒng)計數(shù)列中每個值出現(xiàn)的次數(shù),再從第一個桶傾倒到最后一個桶bucket_list=[0 for n in range(max(num_list)-min(num_list)+1)]#創(chuàng)建min~max這么多個桶for n in range(len(num_list)):#對于當前值bucket_list[num_list[n]-min(num_list)]+=1#添加到值對應(yīng)的桶內(nèi) 即對應(yīng)桶計數(shù)+1result_list=[]#結(jié)果列表for n in range(len(bucket_list)):#對于每個桶if bucket_list[n]!=0:#如果桶內(nèi)有數(shù)result_list+=[n+min(num_list)]*bucket_list[n]#直接把桶里的所有數(shù)倒出來return result_listdef radix_sort(num_list):#基數(shù)排序 比較位數(shù)上的值#比較每一位上的數(shù)字大小 當每一位比較完成排序也就完成pos_list=[]#負數(shù)數(shù)列neg_list=[]#非負數(shù)數(shù)列for num in num_list:#對負數(shù)和非負數(shù)分別處理if num<0:neg_list.append(num)if num>=0:pos_list.append(num)if len(neg_list)!=0:#如果有負數(shù)neg_num_digit=0#初始位數(shù)while neg_num_digit總結(jié)
以上是生活随笔為你收集整理的list 排序_十个必知的排序算法|Python实例系列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何从零开始学android?
- 下一篇: python数据可视化源码_Python