【算法】常用的排序算法的Python实现

jupyter notebook 导出的
包括:插入排序/希尔排序;冒泡排序/快速排序;简单选择排序/堆排序;归并排序

xixi=[1,3,5,7,9,2,4,6,8,10]
#插入排序;空间O(1);时间O(n^2)
def insert_sort(lst):
    lst=lst[:]#避免替换
    for i in range(1,len(lst)):
        temp=lst[i]
        j=i
        while j>0 and lst[j-1]>temp:#寻找插入点
            lst[j]=lst[j-1]
            j-=1
        lst[j]=temp
    return lst
print(insert_sort(xixi))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#希尔排序:O(1);O(nlogn)~O(n^2)
def shell_sort(lst):
    lst=lst[:]#避免覆盖
    num=step=len(lst)
    while True:
        step=step//3+1
        for i in range(step,num):#除跳跃外,与插入一致
            temp=lst[i]
            j=i
            while j>0 and lst[j-step]>temp:#跳跃寻找插入点
                lst[j]=lst[j-step]
                j-=step
            lst[j]=temp
        if step<=1:
            break
    return lst
shell_sort(xixi)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#冒泡排序/交换排序;空间O(1),时间O(n^2)
def bubble_sort(lst):
    lst=lst[:]#避免替换
    for i in range(len(lst)-1):#n-1次循环
        for j in range(1,len(lst)-i):#每一轮后最大的在最后面
            if lst[j-1]>lst[j]:
                lst[j-1],lst[j]=lst[j],lst[j-1]
    return lst
print(insert_sort(xixi))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#快速排序;O(nlogn)~O(n);O(nlogn)
def quick_sort(lst):
    lst=lst[:]#避免替换
    qsort_rec(lst,0,len(lst)-1)
    return lst

def qsort_rec(lst,left,right):
#     print(lst,left,right)
    if left>=right:
        return
    i=left
    j=right
    pivot=lst[i]
    while i<j:
        while i<j and lst[j]>=pivot:#j向左扫描,找小于pivot的记录
            j-=1
        lst[i]=lst[j]
        while i<j and lst[i]<=pivot:#i向右扫描,找大于pivot的记录
            i+=1
        lst[j]=lst[i]
    lst[i]=pivot
    qsort_rec(lst,left,i-1)#排序左侧
    qsort_rec(lst,i+1,right)#排序右侧
print(quick_sort(xixi))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#简单选择排序;空间O(1);时间O(n^2)
def select_srot(lst):
    lst=lst[:]#避免替换
    for i in range(len(lst)-1):
        k=i
        for j in range(i,len(lst)):#查找最小位置
            if lst[j]<lst[k]:
                k=j
        if i!=k:
            lst[i],lst[k]=lst[k],lst[i]
    return lst
print(insert_sort(xixi))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#堆排序;O(1),O(nlogn)
def heap_sort(lst):
    lst=lst[:]#避免覆盖
    num=len(lst)
    #搭建大顶堆
    for i in range(0,num//2)[::-1]:
        heap_adjust(lst,i,num)
    #堆顶记录与最后一个记录交换
    for i in range(0,num)[::-1]:
        lst[0],lst[i]=lst[i],lst[0]
        heap_adjust(lst,0,i)
    return lst

def heap_adjust(lst,i,size):
    left=2*i+1
    right=2*i+2
    max=i
    if i<size//2:
        if left<size and lst[left]>lst[max]:
            max=left
        if right<size and lst[right]>lst[max]:
            max=right
        if max!=i:
            lst[max],lst[i]=lst[i],lst[max]#实现本级交换
            heap_adjust(lst,max,size)#调整交换后的子结点
                       
heap_sort(xixi)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#归并排序;O(n);O(nlogn)
def merge_sort(lst):
    if len(lst)<=1:
        return lst
    num=len(lst)//2
    left=merge_sort(lst[:num])
    right=merge_sort(lst[num:])
    return merge(left,right)

def merge(left,right):
    i,j=0,0
    result=[]
    while i<len(left) and j<len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i+=1
        else:
            result.append(right[j])
            j+=1
    result+=left[i:]
    result+=right[j:]
    return result

merge_sort(xixi)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
xixi
[1, 3, 5, 7, 9, 2, 4, 6, 8, 10]

随手补个煎饼排序,挺有趣的

xixi=[2,4,6,8,10,1,3,5,7,9]
def pancake_sort(lst):
    lst=lst[:]
    for i in range(len(lst))[::-1]:
        #找到最大的那个
        # maxIndex=0
        # for j in range(1,i+1):
        #     if lst[j]>lst[maxIndex]:
        #         maxIndex=j
        #求最大的位置
        maxIndex=lst[:i+1].index(max(lst[:i+1]))
        #翻面一次
        lst=lst[:maxIndex+1][::-1]+lst[maxIndex+1:]
        #翻面二次
        lst=lst[:i+1][::-1]+lst[i+1:]
    return lst
print(pancake_sort(xixi))

快速排序优化——尾递归,每一次循环,左侧的交给递归处理,右侧再拆分左右给递归处理,知道最右只剩1个不需要处理

#快速排序;O(nlogn)~O(n);O(nlogn)
def quick_sort(lst):
    lst=lst[:]#避免替换
    qsort_rec(lst,0,len(lst)-1)
    return lst

def qsort_rec(lst,left,right):
#     print(lst,left,right)
    while right>left:
#     if left>=right:
#         return
        i=left
        j=right
        pivot=lst[i]
        while i<j:
            while i<j and lst[j]>=pivot:#j向左扫描,找小于pivot的记录
                j-=1
            lst[i]=lst[j]
            while i<j and lst[i]<=pivot:#i向右扫描,找大于pivot的记录
                i+=1
            lst[j]=lst[i]
        lst[i]=pivot
        qsort_rec(lst,left,i-1)#排序左侧
#         qsort_rec(lst,i+1,right)#排序右侧
        left+=1
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容

  • 排序大的分类可以分为两种:内排序和外排序。在排序过程中,全部记录存放在内存,则称为内排序,如果排序过程中需要使用外...
    文哥的学习日记阅读 997评论 2 10
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 5,183评论 0 52
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 3,729评论 0 15
  • 听着英语听力写这篇记事,寝室的同学,一个在打电话,一个在洗漱,一个在床上玩手机。 今天失约了,没有去图书馆。在寝室...
    萧咲薇阅读 303评论 0 0
  • 今天第一次在带教老师的指导下给病人做鞘内药物注射。老师提醒了平时我没有注意到的几个小细节,在这里分享给大家: 先来...
    tribbie阅读 21,862评论 2 7