Python排序算法

Python排序算法

下面所有的排序方法都会使用swap函数,来交换两个列表中的位置,代码如下所示:

def swap(lyst,i,j):
    temp = lyst[i]
    lyst[i]=lyst[j]
    lyst[j]=temp

1.选择排序:

原理(整数列表从小到大排序):先搜索整个列表,找到最小项的位置下标,如果不是第一项,就把第一项跟最小项位置对调,之后再搜索第二项到最后一项,重复操作。

大致流程:

未排序的列表第一轮之后第二轮之后第三轮之后第四轮之后
51*111
332*22
15*53*3
223*5*4*
44445*
def selectionSort(lyst):
    i=0
    while i < len(lyst) -1:#做n-1次搜索
        minIndex = i#先以搜索范围内最前面的项为最小项
        j = i + 1
        while j < len(lyst):#开始搜索
            if lyst[j] < lyst[minIndex]:
                minIndex = j
            j += 1
        if minIndex != i:#如果最前面的项和最小项不是同一项,交换这两项
            swap(lyst,minIndex,i)
        i += 1

这个过程中,对于大小为n的列表,最外侧循环执行n-1次,内侧循环第一次执行n-1次,第二次n-2次。。。最后一次n次,因此一共要执行(n-1)+(n-2)+…+1=n(n-1)/2次,时间复杂度为O(n^2)

2.冒泡排序:

策略:从列表开头处开始,并且比较一对数据项,直到移动到列表末尾,每当成对的两项之间的顺序不正确时,算法就交换其位置,这个过程的效果就是将最大项以冒泡的方式排到列表的末尾。然后,算法从列表第二项开始再重复这个过程,直到从列表最后一项开始执行。

未排序的列表第1轮之后第2轮之后第3轮之后第4轮之后
54*444
45*2*22
225*1*1
1115*3*
33335*

python代码实现如下:

def bubbleSort(lyst):
    n=len(lyst)
    while n > 1:#执行完,需要n-1次冒泡
        i = 1#开始冒泡排序
        while i < n:
            if lyst[i] < lyst[i-1]:#如果前项大于后项,那么这两项交换
                swap(lyst,i,i-1)
            i += 1
        n -= 1

外侧必执行n-1次,内侧也是从n-1次执行到1次,所以时间复杂度和选择排序是一样的,都是O(n^2)

这个算法有一种改进,通过在提前设置一个bool类型的标志,如果发生了调用swap函数,那么bool改变值,但如果没有,函数直接退出,这样的话,在最好的情况下,只需要把数据遍历一遍就可以了,但平均和最坏情况还是O(n^2),代码如下:

def bubbleSort(lyst):
    n=len(lyst)
    while n > 1:
        swapped = False
        i = 1
        while i < n:
            if lyst[i] < lyst[i-1]:
                swap(lyst,i,i-1)
                swapped = True
            i += 1
      if not swapped:return
      n -= 1

3.插入排序:

插入排序的工作方式像许多人排序一手扑克牌。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。拿在左手上的牌总是排序好的,原来这些牌是桌子上牌堆中顶部的牌.

插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序.

这么理解可能有些抽象,我们直接用图标展示:

未排序的列表第1轮之后第2轮之后第3轮之后第4轮之后
221*11
5←5(没有插入)222
11←54*3*
444←54
3333←5

代码实现:

def insertionSort(lyst):#可以想象成玩斗地主的时候,给手里的牌整理的过程
    i = 1
    while i < len(lyst):
        itemToInsert = lyst[i]#这里其实相当于把扑克牌拿出来
        j=i-1
        while j >= 0:#拿出来的扑克牌跟在它前面所有的扑克牌相比较,如果有一个比拿出来的扑克牌大,拿出来的扑克牌就插入到那个比它大的扑克牌前面的位置
            if itemToInsert < lyst[j]:
                lyst[j+1] = lyst[j]
                j -= 1
            else:break
        lyst[j+1] = itemToinsert
        i += 1

假设所有都是未排序的(比方54321)那么它每一次还是要向选择排序一样每一项都要遍历,复杂度为O(n^2),但如果有排好序的,复杂度就会降低,排好序的项越多,复杂度越低,当全部都是排好序的时候,复杂度是O(n)

4.快速排序

主要思想是分而治之,把一个列表分成不同的小份,运用递归解决(具体比较抽象,建议看视频)

def quicksort(array)
	if len(array)<2:
        return array
    else:
        baseValue=array(0)
        less=[m for m in array[1:] if m < baseValue]
        eqal=[w for w in array if w==baseValue]
        greater=[n for n in array[1:] if n >baseValue]
    return quickSort(less)+equal+quickSort(greater)

5.归并排序

# 记录归并排序
def MergeSort(lists):
    if len(lists) <= 1:
        return lists
    middle = len(lists)//2
    left = MergeSort(lists[:middle])
    right = MergeSort(lists[middle:])
    return merge(left, right)


def merge(a, b):
    c = []
    h = j = 0
    while j < len(a) and h < len(b):
        if a[j] < b[h]:
            c.append(a[j])
            j += 1
        else:
            c.append(b[h])
            h += 1
    if j == len(a):
        for i in b[h:]:
            c.append(i)
    else:
        for i in a[j:]:
            c.append(i)

    return c
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值