Python版数据结构与算法-排序算法,实现了冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序

排序 Sort

1、冒泡排序 BubbleSort

在这里插入图片描述

(1) 冒泡排序多次遍历列表。它比较相邻的元素,将不合顺序的交换。每一轮遍历都将下一个最大值放到正确的位置上。时间复杂度是 O ( n 2 ) O(n^2 ) O(n2)

def BubbleSort(nums: list):
    for i in range(len(nums)-1, 0, -1):
        for j in range(i):
            if nums[j] > nums[j+1]:
                nums[j], nums[j+1] = nums[j+1], nums[j]
    return nums

(2) 鸡尾酒排序奇数次寻找最大值,偶数次寻找最小值。适用于渴望单次获得最大值最小值的情况。时间复杂度是 O ( n 2 ) O(n^2 ) O(n2)

def BubbleSort2(lst: list):
    L, R = 0, len(lst)-1
    for j in range(len(lst)-1, 0, -1):
        if (j-len(lst)+1) %2:
            for i in range(R-1, L-1, -1):
                if lst[i+1] < lst[i]:
                    lst[i], lst[i+1] = lst[i+1], lst[i]
            L += 1
        else:
            for i in range(L, R, 1):
                if lst[i] > lst[i+1]:
                    lst[i], lst[i+1] = lst[i+1], lst[i]
            R -= 1
    return lst

(3) 短冒泡排序在遇到已排序列表时会跳出。最优时间复杂度为 O ( n ) O(n) O(n),最坏时间复杂度还是 O ( n 2 ) O(n^2) O(n2)

def shortBubbleSort(lst: list):
    l = len(lst)
    if l <= 1: return lst
    for i in range(l-1, 0, -1):
        flag = False
        for j in range(i):
            if lst[j] > lst[j+1]:
                lst[j], lst[j+1] = lst[j+1], lst[j]
                flag = True
        if not flag: return lst
2、选择排序 SelectionSort

在这里插入图片描述

(1) 选择排序是冒泡排序的修改。每一轮遍历都只找出最大值放到正确的位置上。时间复杂度是 O ( n 2 ) O(n^2 ) O(n2)

def SelectionSort(List):
    for i in range(len(List)-1, 0, -1):
        Max = 0
        for j in range(i):
            if List[j+1] > List[Max]:
                Max = j+1
        List[i], List[Max] = List[Max], List[i]
3、插入排序 InsertionSort

在这里插入图片描述
在这里插入图片描述

(1) 插入排序在列表较低的一端维护一个有序的子列表,并逐个将每个新元素“插入”这个子列表。时间复杂度是 O ( n 2 ) O(n^2 ) O(n2)

def InsertionSort(List):
    for i in range(1, len(List)):
        temp = List[i]
        j = i
        while j >= 1 and List[j-1] > temp:
            List[j] = List[j-1]
            j -= 1
        List[j] = temp
4、希尔排序 ShellSort

在这里插入图片描述
在这里插入图片描述

(1) 希尔排序也称“递减增量排序”,它对插入排序做了改进,将列表按照步长分成数个子列表,并对每一个子列表应用插入排序。对于固定增量, δ ≤ ∣ L i s t ∣ δ\leq\sqrt{|List|} δList g a p = ∣ L i s t ∣ / / δ gap={|List|} //δ gap=List//δ。时间复杂度是 O ( n 3 / 2 ) O(n^{3/2}) O(n3/2)

def ShellSort(List, delta):
    gap = len(List) // delta
    while gap > 0:
        for start in range(gap):
            for i in range(start+gap, len(List), gap):
                temp = List[i]
                j = i
                while j >= gap and List[j-gap] > temp:
                    List[j] = List[j-gap]
                    j -= gap
                List[j] = temp
        gap //= delta
5、归并排序 MergeSort

在这里插入图片描述在这里插入图片描述

(1) 归并排序使用分治策略,将列表不断一分为二,然后递归调用归并排序。归并是指将两个较小的有序列表归并为一个有序列表的过程。时间复杂度是 O ( n l o g n ) O(nlog n) O(nlogn)

def MergeSort(List):
    def _sort(L, R, List):
        if L != R:
            mid = (L+R) // 2
            _sort(L, mid, List)
            _sort(mid+1, R, List)
            i = L; j = mid+1
            s = []
            while i <= mid and j <= R:
                if List[i] < List[j]:
                    s.append(List[i]); i += 1
                else:
                    s.append(List[j]); j += 1
            while i <= mid:
                s.append(List[i]); i += 1
            while j <= R:
                s.append(List[j]); j += 1
            for i in range(len(s)):
                List[L+i] = s[i]
    _sort(0, len(List)-1, List)
6、快速排序 QuickSort

在这里插入图片描述
在这里插入图片描述

(1) 快速排序使用分治策略,但不使用额外的存储空间。选取基准值,通过首尾指针判断大小找到基准值的正确位置,接着把列表一分为二递归调用。时间复杂度是 O ( n l o g n ) O(nlog n) O(nlogn)

def QuickSort(List):
    def _sort(List, first, last):
        if last > first:
            split = partition(List, first, last)
            _sort(List, first, split-1)
            _sort(List, split+1, last)
    _sort(List, 0, len(List)-1)

def partition(List, first, last):
    datum = List[first] #基准值

    if last-first > 3: #三数取中法:取前三个数的中值作为基准值。
        d1,d2 = List[first+1],List[first+2]
        d1,d2 = (d1,d2) if d1>d2 else (d2,d1)
        datum=min(d1,datum); datum=max(d2,datum)

    left = first+1
    right = last
    done = False
    while not done:
        while left <= right and List[left] <= datum:
            left += 1
        while List[right] >= datum and right >= left:
            right -= 1
        if right < left: done = True
        else: List[left],List[right] = List[right],List[left]
    List[first], List[right] = List[right], List[first]
    return right
7、堆排序 heapq模块

heapq里接口操作的对象是list。逻辑结构为一个完全二叉树。时间复杂度是 O ( n l o g n ) O(nlog n) O(nlogn)

import heapq

#添加元素。
heapq.heappush(heap:list, item:float)
'''
data = [97, 38, 27, 50, 76, 65, 49, 13]
heap = []
for n in data:
heapq.heappush(heap, n)'''

#列表堆化重排
heapq.heapify(List:list)
'''
data = [97, 38, 27, 50, 76, 65, 49, 13]
heapq.heapify(data)'''

#删除并返回堆顶元素,即heap中最小的元素。
heapq.heappop(heap:list)
#替换并返回堆顶元素。
heapreplace(heap:list, item:float)
#添加元素,并返回重新堆化后的堆顶元素。
heapq.heappushpop(heap:list, item:float)

#merge是多路归并排序。
heapq.merge(heap:list[,heap:list [,heap:list [...]]])

#获取最大或者最小的n个数。
heapq.nlargest(n, iterable, key=None)
#结果上等价于sorted(iterable, key=key, reverse=True)[:n]
heapq.nsmallest(n, iterable, key=None)
#结果上等价于sorted(iterable, key=key)[:n]
8、桶排序 BucketSort

桶排序特别浪费空间。时间复杂度是 O ( n ) O(n) O(n)

def BucketSort(nums):
    minv, maxv = min(nums), max(nums)
    countn = [0]*(maxv-minv+1)
    for i in nums:
        countn[i-minv] += 1
    n = 0
    for i in range(len(countn)):
        p=countn[i]
        while countn[i] and p:
            nums[n]=i+minv
            n += 1; p-=1

完整代码下载地址:Python版数据结构与算法-排序算法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员柳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值