常见排序算法Python

排序

  • 冒泡排序O(n^2)
  • 选择排序O(n^2)
  • 插入排序O(n^2)
  • 希尔排序O(n)-O(n^2)
  • 归并排序O(nlogn)
  • 快速排序O(nlogn)-O(n^2)

1、冒泡排序

1.1、常规

def bubbleSort(alist):
    for epoch in range(len(alist) - 1, 0, -1):
        for i in range(epoch):
            if alist[i] > alist[i+1]:
                alist[i], alist[i+1] = alist[i+1], alist[i]
alist = [25,1,2,45,25,16,78,99,9,7]
bubbleSort(alist)
alist
[1, 2, 7, 9, 16, 25, 25, 45, 78, 99]

1.2、短冒泡

def shortBubbleSort(alist):
    exchanges = True
    passnum = len(alist-1)
    while passnum > 0 and exchanges:
        exchanges = False
        for i in range(passnum):
            if alist[i] > alist[i+1]:
                exchanges = True
                alist[i], alist[i+1] = alist[i+1], alist[i]
        passnum  -= 1
alist = [25,1,2,45,25,16,78,99,9,7]
bubbleSort(alist)
alist
[1, 2, 7, 9, 16, 25, 25, 45, 78, 99]

2、选择排序

def selectionSort(alist):
    for  epoch in range(len(alist)-1, 0, -1):
        positionOfMax = 0
        for i in range(1, 1 + epoch):# 每轮最大值的位置为0,所以从1开始比较;因为列表索引不包括右边界,所以epoch要加上1
            #寻找该轮最大值的位置
            if alist[positionOfMax] < alist[i]:
                positionOfMax = i
        # 最大值位置放置到对应的位置
        alist[positionOfMax], alist[epoch] = alist[epoch], alist[positionOfMax]
    
alist = [25,1,2,45,25,16,10, 78,99,9,7]
selectionSort(alist)
alist
[1, 2, 7, 9, 10, 16, 25, 25, 45, 78, 99]

3、插入排序

  • 插入排序式中保持在列表的低位是已经排序的子列表,然后后面的项逐个插入到其中。
def insertionSort(alist):
    for index in range(1, len(alist)):
        currentvalue = alist[index]
        position = index
        while position > 0 and alist[position-1] > currentvalue:
            alist[position] = alist[position-1]
            position -= 1
        alist[position] = currentvalue
        
alist = [25,1,2,45,25,16,10, 78,99,9,7]
insertionSort(alist)
alist
[1, 2, 7, 9, 10, 16, 25, 25, 45, 78, 99]

4、希尔排序

  • 希尔排序是一种不稳定的排序法,即如果列表中有两个相同的值,则它俩的相对位置有可能发生改变
def shellSort(alist):
    sublistcount = len(alist) // 2
    while sublistcount > 0:
        for startposition in range(sublistcount):
            gapInsertionSort(alist, startposition, sublistcount)
        print("增量为{},排序后为{}".format(sublistcount, alist))
        
        sublistcount = sublistcount // 2

        
        
def gapInsertionSort(alist,start, gap):
    for i in range(start + gap,len(alist),gap):
        currentvalue = alist[i]
        position = i
        while position >= gap and alist[position - gap] > currentvalue:
            alist[position] = alist[position - gap]
            position = position - gap
        alist[position] = currentvalue
alist = [25,1,2,45,25,16,10, 78,99,9,7,19]
shellSort(alist)
alist
增量为6,排序后为[10, 1, 2, 9, 7, 16, 25, 78, 99, 45, 25, 19]
增量为3,排序后为[9, 1, 2, 10, 7, 16, 25, 25, 19, 45, 78, 99]
增量为1,排序后为[1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 78, 99]





[1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 78, 99]

5、归并排序

  • 使用分而治之的策略,会使用额外的存储空间
  • 是一种稳定的排序
def mergeSort(alist):
    print("分割:" ,alist)
    if len(alist) > 1:
        mid = len(alist) // 2
        
        # 这里使用切片导致会使用额外的空间
        lefthalf = alist[:mid]
        righthalf = alist[mid:]
        mergeSort(lefthalf)
        print("=============================")
        mergeSort(righthalf)
        
        
        i, j , k = 0, 0 ,0
        while i < len(lefthalf) and j < len(righthalf):
            if lefthalf[i] < righthalf[j]:
                alist[k] = lefthalf[i]
                i += 1
            else:
                alist[k] = righthalf[j]
                j += 1
            k += 1
        while i < len(lefthalf):
            alist[k] = lefthalf[i]
            i += 1
            k += 1
        while j < len(righthalf):
            alist[k] = righthalf[j]
            j += 1
            k += 1
    print("合并: ", alist)
alist = [25,1,2,45,25,16,10, 78,99,9,7,19]
mergeSort(alist)

分割: [25, 1, 2, 45, 25, 16, 10, 78, 99, 9, 7, 19]
分割: [25, 1, 2, 45, 25, 16]
分割: [25, 1, 2]
分割: [25]
合并:  [25]
=============================
分割: [1, 2]
分割: [1]
合并:  [1]
=============================
分割: [2]
合并:  [2]
合并:  [1, 2]
合并:  [1, 2, 25]
=============================
分割: [45, 25, 16]
分割: [45]
合并:  [45]
=============================
分割: [25, 16]
分割: [25]
合并:  [25]
=============================
分割: [16]
合并:  [16]
合并:  [16, 25]
合并:  [16, 25, 45]
合并:  [1, 2, 16, 25, 25, 45]
=============================
分割: [10, 78, 99, 9, 7, 19]
分割: [10, 78, 99]
分割: [10]
合并:  [10]
=============================
分割: [78, 99]
分割: [78]
合并:  [78]
=============================
分割: [99]
合并:  [99]
合并:  [78, 99]
合并:  [10, 78, 99]
=============================
分割: [9, 7, 19]
分割: [9]
合并:  [9]
=============================
分割: [7, 19]
分割: [7]
合并:  [7]
=============================
分割: [19]
合并:  [19]
合并:  [7, 19]
合并:  [7, 9, 19]
合并:  [7, 9, 10, 19, 78, 99]
合并:  [1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 78, 99]

另一种写法

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


def merge_sort(lists):
    if len(lists) <= 1:
        return lists
    middle = len(lists) // 2
    left = merge_sort(lists[:middle])
    right = merge_sort(lists[middle:])
    return merge(left, right)


if __name__ == '__main__':
    a = [14, 2, 34, 43, 21, 19]
    print (merge_sort(a))

[2, 14, 19, 21, 34, 43]

6、快速排序

  • 使用分而治之的策略,不使用额外的存储空间
def quickSort(alist):
    quickSortHelper(alist, 0, len(alist)-1)
    
def quickSortHelper(alist, first, last):
    if first < last:
        splitpoint = partition(alist, first,last)
        quickSortHelper(alist, first, splitpoint - 1)
        quickSortHelper(alist, splitpoint + 1, last)

def partition(alist, first, last):
    pivotvalue = alist[first]
    leftmark = first + 1
    rightmark = last
    done = False
    while not done:
        while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
            leftmark = leftmark + 1
        while rightmark >= leftmark and alist[rightmark] >= pivotvalue:
            rightmark = rightmark - 1
            
        if rightmark < leftmark:
            done = True
        else:
            alist[leftmark], alist[rightmark] = alist[rightmark], alist[leftmark]
        
    alist[first], alist[rightmark] = alist[rightmark], alist[first]
    return rightmark
            
alist = [25,1,2,45,25,16,60,10, 78,99,9,7,19]
quickSort(alist)
alist
[1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 60, 78, 99]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值