zoukankan      html  css  js  c++  java
  • 常见的排序算法的总结及python代码实现

    • 冒泡排序
    • 选择排序
    • 直接插入排序
    • 快速排序
    • 堆排序
    • 归并排序
    • 希尔排序
    • 总结
    • 作业

    一、冒泡排序

    思路:n个数需要进行n-1趟排序,每一趟排序就是两个相邻的数组比较,交换位置。第i趟排序需要交换n-i-1次

    代码:

    #Author:Yueru Sun
    def bubble_sort(data):
        for i in range(0,len(data)-1):
            for j in range(0,len(data)-i-1):
                if data[j]>data[j+1]:
                    data[j],data[j+1]=data[j+1],data[j]
        return data
    print(bubble_sort([1,3,4,21,10]))
    ###################################################
    #时间复杂度o(n*n)

    优化的代码:(最好的情况:针对原来排序的序列本来就是有序的,时间复杂的变为0(n))

    就是如果出现某一趟排序未交换位置,那么就可以直接break不进行下一趟排序了

    def bubble_sort(data):
        for i in range(0,len(data)-1):
            flag=False#表示未交换
            for j in range(0,len(data)-i-1):
                if data[j]>data[j+1]:
                    data[j], data[j + 1] = data[j + 1], data[j]
                    flag=True
            if flag=='False':
                break
        return data
    print(bubble_sort([1,3,4,21,10]))

    二、选择排序

    原理:n个元素需要进行n-1趟排序,每一趟都会选出最小(大)的那个数组放到正确的位置,下一趟就遍历表中的剩下的元素,继续。。。

    代码:

    def select_sort(data):
        for i in range(0,len(data)-1):
            min_num=i#最小元素的下标,默认是每一趟的第一个数字
            for j in range(i+1,len(data)):#每一趟需要在data[i+1]~data[len(data)-1]中找到最小(大)的那个数字的位置
                if data[j]<data[min_num]:
                    min_num=j#把最小元素的下标修改未j
            #for语句执行结束后就表示在这趟循环中找到了 在data[i+1]~data[len(data)-1]中找到最小(大)的那个数字 的位置
            if min_num!=i:#如果最初假定的i不是
                data[i],data[min_num]=data[min_num],data[i]
        return data
    print(select_sort([5,3,2,1,10]))
    时间复杂度:o(n*n)

    三、直接插入排序

    原理:列表被分为有序区和无序区,默认最初的有序区是第一个元素。每次从无序区中选择一个元素,插入到有序区位空置,直到无序区变

    代码:

    def insert_sort(data):
        for i in range(0,len(data)):
            key=data[i]
            j=i-1#有序序列的最后一个元素
            while j>=0:#当有序序列不为空
                if data[j]>key:
                    data[j+1]=data[j]#j之后的元素后移
                    data[j]=key#把key放到第j个位置
                j=j-1#往前移动
        return data

    时间复杂度:o(n*n)

    四、快速排序

    原理:每一趟循环使得一个元素归位,同时列表被分成两部分,左边的都比归位元素小,右边的都比归位元素大

    代码:

    def quick_sort(data,left,right):
        if left<right:
            #分割成两部分
            mid=partion(data,left,right)
            #递归实现
            quick_sort(data,left,mid-1)
            quick_sort(data,mid,right)
    def partion(data,left,right):
        temp=data[left]
        while left<right:
            while left<right and temp<=data[right]:
                right-=1
            data[left]=data[right]
            while left<right and temp>=data[left]:
                left-=1
            data[right]=data[left]
        data[left]=temp#或者写data[right]=temp,因为此时left和right相遇了,相遇的位置就是temp存放的位置
        return left
    

    平均时间复杂度:o(n*logn)

    最坏的情况:o(n*n)

    五、堆排序

    原理:

    建立堆
    得到堆顶元素,为最大元素
    去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序。
    堆顶元素为第二大元素。
    重复步骤3,直到堆变空。

    可以参考:https://www.cnblogs.com/chengxiao/p/6129630.html

    https://blog.csdn.net/sxhelijian/article/details/50295637

    代码:

    def heap_sort(data):
        n=len(data)
        for i in range(n//2-1,-1,-1):#建立堆,只需要调整堆中的父节点
            sift(data,i,n-1)
        for i in range(n-1,-1,-1):#从堆的最后一个元素开始调整
            data[0],data[i]=data[i],data[0]
            sift(data,0,i-1)
    def sift(data,low,high):#low是需要调整的堆的堆顶序号,high是需要调整的堆的最后一个元素的序号
        i=low
        j=2*i+1
        tmp=data[i]
        while j<=high:
            if j<=high and data[j]<data[j+1]:
                j+=1
            if tmp<data[j]:
                data[i]=data[j]
                i=j
                j=2*i+1
            else:
                break
        data[i]=tmp

    时间复杂度:o(n*logn)

    六、归并排序

    原理:分治的思想。www.cnblogs.com/chengxiao/p/6194356.html

    代码:

    #归并
    def merge(data,low,mid,high):
        i=low
        j=mid+1
        ltmp=[]
        while i<mid and j<high:
            if data[i]<data[j]:
                ltmp.append(data[i])
                i+=1
            else:
                ltmp.append(data[j])
                j+=1
        while j<=mid:
            ltmp.append(data[i])
            i+=1
        while j<=high:
            ltmp.append(data[j])
            j+=1
        data[low:high+1]=ltmp
    
    def mergesort(data,low,high):
        if low<high:
            mid=(low+high)//2
            mergesort(data,low,mid)
            mergesort(data,mid+1,high)
            merge(data,low,mid,high)

    时间复杂度:O(nlogn)
    空间复杂度:O(n)

    七、希尔排序

    原理:

    希尔排序是一种分组插入排序算法。
    首先取一个整数d1=n/2,将元素分为d1个组,每组相邻量元素之间距离为d1,在各组内进行直接插入排序;
    取第二个整数d2=d1/2,重复上述分组排序过程,直到di=1,即所有元素在同一组内进行直接插入排序。

    希尔排序的最后一趟就是直接插入排序

    代码:

    #希尔排序
    def sheel_sort(data):
        gap=len(data)//2
        while gap>0:
            for i in range(gap,len(data)):
                key=data[i]
                j=i-gap
                while j>=0:
                    if key<data[j]:
                        data[j+gap]=data[j]
                        data[j + gap] = key
                    j-=gap
    
            gap/=2
    时间复杂度:时间复杂度: O((1+τ)n)

           

  • 相关阅读:
    取模 分数取模 快速幂 费马小定理
    “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛 部份签到题
    shell 脚本
    pyhcl语法
    数据库实验1 SQL
    杂七杂八 Ubuntu Linux
    Kattis, Kattis 的一些问题题解
    Meow Factor 【暴力】
    解决 Eclipse 项目有红感叹号的方法
    RuntimeException与CheckedException
  • 原文地址:https://www.cnblogs.com/mesunyueru/p/8974734.html
Copyright © 2011-2022 走看看