常见的排序算法的总结及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)

       

原文地址:https://www.cnblogs.com/mesunyueru/p/8974734.html