排序算法python实现

这里主要使用python语言实现常见的排序算法。例如:冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、堆排序、计数排序、桶排序、基数排序。

1、冒泡排序

原理:比较相邻的两个元素,如果前一个元素比第二个元素大,则交换两个元素
时间复杂度:平均/最差时间复杂度 O(n**2),最好时间复杂度O(n)
空间复杂度:O(1)
是否稳定:稳定

nums = [44, 3, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]

n = len(nums)
for i in range(n):  # 控制遍历的次数
    for j in range(n - 1 - i):  # 遍历没有排序完成的数
        if nums[j + 1] < nums[j]:  # 两两比较
            nums[j], nums[j + 1] = nums[j + 1], nums[j]  # 交换元素
print(nums)
# [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

2、选择排序

原理:每次选择最小(大)的元素放到序列的开始(末尾)
时间复杂度:O(n**2)
空间复杂度:O(1)
是否稳定:稳定

nums = [44, 3, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]

n = len(nums)
for i in range(n):  # 进行n次选择,每次为i的位置上选择从剩下的数中选择一个最小的
    minIndex = i  # 假定最小元素的下标
    for j in range(i + 1, n):  # 遍历剩下的元素,找出最小元素的下标
        if nums[minIndex] > nums[j]:
            minIndex = j

    nums[i], nums[minIndex] = nums[minIndex], nums[i]  # 交换最小元素和当前元素

print(nums) 
# [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

3、插入排序

原理:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入
时间复杂度:平均/最差时间复杂度 O(n**2),最好时间复杂度O(n)
空间复杂度:O(1)
稳定性:稳定

nums = [44, 3, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
n = len(nums)

for curIndex in range(1, n):
    cur = nums[curIndex]  # 为第i个数找到合适的位置
    preIndex = curIndex - 1
    while 0 <= preIndex and cur < nums[preIndex]:  # 如果前面的数大于当前数,继续向前找
        nums[preIndex + 1] = nums[preIndex]
        preIndex -= 1
    nums[preIndex + 1] = cur

print(nums) 
# [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

4、快速排序

算法原理:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
时间复杂度:平均/最好时间复杂度 O(nlog2n),最差时间复杂度O(n**2)
空间复杂度:O(nlog2n)
稳定性:不稳定

def partition(arr, left, right):
    # 目的是找到pivot的正确位置:使得以pivot为分割,pivot左边的数全部小于它,pivot右边的数全部大于它
    # 1、右边的数和pivot相比,如果右边的数大于pivot,继续往左边找;直到一个数小于pivot,把这个数放在数组的最左边,也就是pivot的原始位置
    # 2、左边的数和pivot相比,如果左边的数小于pivot,继续往右移动;直到一个数大于pivot,把这个数放在之前右边数的位置,把pivot放在当前位置,也就是分割位置,并返回
    pivot = arr[left]
    while left < right:
        while left < right and arr[right] >= pivot:
            right -= 1
        arr[left] = arr[right]
        while left < right and arr[left] <= pivot:
            left += 1
        arr[right] = arr[left]

    arr[left] = pivot

    return left

def quickSort(arr, left, right):
    if left < right:
        partitionIndex = partition(arr, left, right)
        quickSort(arr, left, partitionIndex - 1)
        quickSort(arr, partitionIndex + 1, right)
    return arr

nums = [44, 3, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
left = 0
right = len(nums) - 1
res = quickSort(arr=nums, left=left, right=right)
print(res)
# [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

5、归并排序

原理:算法核心是合并两个有序数组。先局部有序,再整体有序。
时间复杂度:平均/最差/最好时间复杂度 O(nlog2n)
空间复杂度:O(n)
稳定性:稳定

def merge(nums1, nums2):
    # 合并两个有序数组
    res = []
    len1 = len(nums1)
    len2 = len(nums2)
    i, j = 0, 0
    while i < len1 and j < len2:
        if nums1[i] < nums2[j]:
            res.append(nums1[i])
            i += 1
        else:
            res.append(nums2[j])
            j += 1
    if i < len1:
        res += nums1[i:]
    if j < len2:
        res += nums2[j:]
    return res


def merge_sort(nums):
    # 归并排序,使用递归
    n = len(nums)
    if n < 2:
        return nums

    middle = n // 2

    left = merge_sort(nums[:middle])
    right = merge_sort(nums[middle:])
    res = merge(left, right)

    return res


nums = [44, 3, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
res = merge_sort(nums)
print(res) 
# [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

参考

  • 17
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值