排序算法(python版)代码详解

目录

1.冒泡排序

2.选择排序

3.插入排序

4.希尔排序

5.归并排序

6.快速排序


1.冒泡排序

特点:多次遍历列表,比较相邻的元素,将较大值放在正确的位置上。

特别注意!如果列表中有n个元素,那么第一轮遍历要比较n-1对。当遍历完n-1轮后,最小的元素一定在正确的位置上。

#冒泡排序
def bubbleSort(alist):
    for n in range(len(alist)-1,0,-1):
        for i in range(n):
            if alist[i]>alist[i+1]:
                alist[i],alist[i+1]=alist[i+1],alist[i]

if __name__=="__main__":
    alist=[10,9,8,7,6,5,4,3,2,1]
    n=10
    bubbleSort(alist)
    print("排序后的数组:")
    for i in range(n):
        print("%d"%alist[i])

2.选择排序

特点:每次遍历时只做一次交换,每次遍历时寻找最大值,并在遍历完成后就会放在正确的位置上。

若给n个元素排序,则需遍历n-1轮,这是因为最后一个元素要到n-1轮遍历后才就位。

相较于冒泡排序,两者算法的比较次数相同,所以时间复杂度都是O(n^2),但由于减少了交换次数,因此选择排序算法更快。

#选择排序
def selectionSort(alist):
    for n in range(len(alist)-1,0,-1):
        max=0
        for i in range(1,n+1):
            if alist[i]>alist[max]:
                max=i
        alist[n],alist[max]=alist[max],alist[n]
if __name__=="__main__":
    alist=[10,9,8,7,6,5,4,3,2,1]
    n=10
    selectionSort(alist)
    print(alist)

3.插入排序

        通常情况下,我们认为第一个元素时有序的,从元素1到元素n-1,每一轮都将当前元素与有序子列表中的元素进行比较。将比它大的元素右移;当遇到一个比它小的元素或抵达子列表的终点时,就可插入当前元素。

#插入排序
def insertionSort(alist):
    for i in range(1,len(alist)):
        key=alist[i]
        j=i
        while j>0 and alist[j-1]>key: #列表的前一个数大于该key值时,
            alist[j]=alist[j-1]
            j=j-1
        alist[j]=key

if __name__=="__main__":
    alist=[10,99,8,77,16,15,48,3,24,1]
    insertionSort(alist)
    print("排序后的数组:")
    print(alist)

 4.希尔排序

特点:1.当数组长度很大时,若最小值在很末端,用插入排序则要逐一比较,遍历整个序列,非常低效。希尔排序就能很好的规避这个问题:直接利用分组的方式,让前端和末端的元素经行比较。2.一开始n的增量很大,每一个子列表的元素很少,所以对每个列表用插入排序进行内部排序是很高效的;而后随着增量n的不断减小,这个数组是越来越有序的,此时使用插入排序也是很有利的。

#希尔排序
def shellSort(alist):
    n=len(alist)//2
    while n>0:
        for startposition in range(n):#起始位置默认从第一个数开始
            gapInsertionSort(alist, startposition, n)
        n=n//2

def gapInsertionSort(alist,start,gap):
    for i in range(start+gap,len(alist),gap):
        temp = alist[i]
        j = i
        while j >= gap and alist[j - gap] > temp:
            alist[j] = alist[j - gap]
            j -= gap
            alist[j] = temp

if __name__=="__main__":
    alist=[10,99,8,77,16,15,48,3,24,1]
    #alist = [12,34,54,2,3]
    n = len(alist)
    shellSort(alist)
    print("排序后的数组:")
    print(alist)

 5.归并排序

方法:1.将序列中带排序的数字分为若干组,每个数字分成一组;2.将若干组两两合并,保证合并后的组是有序的;3.重复第二步操作直到只剩下一组(当列表为空或只有一个元素,那么它就是有序的)

#归并排序
def mergeSort(alist):
    print("Splitting",alist)
    #拆分
    if len(alist)>1:
        mid=len(alist)//2
        lefthalf=alist[:mid]
        righthalf=alist[mid:]
        mergeSort(lefthalf)
        mergeSort(righthalf)

        # 归并
        i=0  # 初始化第一个子数组的索引
        j=0  # 初始化第二个子数组的索引
        k=0  # 初始归并子数组的索引
        while i<len(lefthalf) and j<len(righthalf):
            if lefthalf[i]<righthalf[j]:  #比较左、右序列哪个数更小
                alist[k]=lefthalf[i] #依次从小到大排序
                i=i+1
            else:
                alist[k]=righthalf[j]
                j=j+1
            k=k+1
        while i<len(lefthalf):
            alist[k]=lefthalf[i]
            i=i+1
            k=k+1
        while j<len(righthalf):
            alist[k]=righthalf[j]
            j=j+1
            k=k+1
    print("Merging",alist)

if __name__=="__main__":
    alist=[10,99,8,77,16,15,48,3,24,1]
    mergeSort(alist)
    print("排序后的数组:")
    print(alist)

 6.快速排序

方法:1.选定基准值key;2.若待排序数小于基准值,放左边;3.若待排序数大于基准值,放右边;4.对左右分别进行以上操作

#快速排序
def quickSort(alist):
    digui(alist,0,len(alist)-1)
def digui(alist,first,last):
    if first<last:
        splitpoint=partition(alist,first,last)
        digui(alist,first,splitpoint-1)
        digui(alist,splitpoint+1,last)
def partition(alist,first,last):
    pivotvalue=alist[first]
    left=first+1
    right=last
    done=False
    while not done:
        while left<=right and alist[left]<=pivotvalue:
            left=left+1
        while alist[right]>=pivotvalue and right>=left:
            right=right-1
        if right<left:
            done=True
        else:
            alist[left],alist[right]=alist[right],alist[left]
    alist[first],alist[right]=alist[right],alist[first]
    return right

if __name__=="__main__":
    alist=[10,99,8,77,16,15,48,3,24,1]
    quickSort(alist)
    print("排序后的数组:")
    print(alist)

总结:

冒泡排序,选择排序,插入排序时间复杂度都为O(n*n)

希尔排序的时间复杂度介于O(n)和O(n*n)之间

归并排序的时间复杂度为O(n*logn)

快速排序的时间复杂度为O(n*logn),但当分割点不靠近列表中部时会降到O(n*n)

(归并排序和快速排序都要使用额外的存储空间)

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值