python 常用排序算法

a = [5, 3, 4, 1, 2, 2]

冒泡排序

def bubble(a):
    """
    冒泡排序 时间复杂度o(n2)
    比较相邻的元素大小,将小的前移,大的后移
    :param a:list
    :return: sorted(a)
    """
    num = 0
    for i in range(len(a) - 1):
        for j in range(len(a) - i - 1):
            if a[j] > a[j + 1]:
                a[j], a[j + 1] = a[j + 1], a[j]
                print(' %s和 %s互换位置, %s -->> %s ' % (a[j], a[j + 1], a[j], a[j + 1]))
                num += 1
    print('移动次数: %s 次' % num)
    print(a)
    return a

选择排序

def selection_sort(a):
    """
    选择排序 时间复杂度o(n2)
    第1趟,在待排序记录r1 ~ r[n]中选出最小的记录,
    将它与r1交换;第2趟,在待排序记录r2 ~ r[n]中选出最小的记录,
    将它与r2交换;以此类推,第i趟在待排序记录r[i] ~ r[n]中选出最小的记录
    :param a: list
    :return: sorted(a)
    """
    num = 0
    for i in range(len(a) - 1):
        min = i
        for j in range(i + 1, len(a)):
            if a[min] > a[j]:
                min = j
        if min != i:
            a[i], a[min] = a[min], a[i]
            print(' %s和 %s互换位置, %s -->> %s ' % (a[i], a[min], a[i], a[min]))
            num += 1
    print('移动次数: %s 次' % num)
    print(a)
    return a

插入排序

def insert_sort(a):
    """
    插入排序 时间复杂度 o(n2)
    插入排序:插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,
    从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序;
    首先将第一个作为已经排好序的,
    然后每次从后的取出插入到前面并排序;
    :param a:list
    :return:sorted(a)
    """
    for i in range(len(a)):
        for j in range(i):
            if a[i] < a[j]:
                a.insert(j, a.pop(i))
                break
    print(a)
    return a

希尔排序

def shell_sort(a):
    """
    希尔排序 时间复杂度 o(nlogn) or o(n^(1.3—2))
    希尔排序是把记录按下标的一定增量分组,
    对每组使用直接插入排序算法排序;
    随着增量逐渐减少,每组包含的关键词越来越多,
    当增量减至1时,整个文件恰被分成一组,算法便终止
    :param a:list
    :return:sorted(a)
    """
    num = 0
    gap = len(a)
    while gap > 1:
        gap = gap // 2  ##  取商
        for i in range(gap, len(a)):
            for j in range(i % gap, i, gap):
                if a[i] < a[j]:
                    a[i], a[j] = a[j], a[i]
                    print(' %s和 %s互换位置, %s -->> %s ' % (a[i], a[j], a[i], a[j]))
                    num += 1
    print('移动次数: %s 次' % num)

    print(a)
    return a

快速排序

def quick_sort(a):
    """
    快速排序 时间复复杂度nlogn
    通过一趟排序将要排序的数据分割成独立的两部分,
    其中一部分的所有数据都比另外一部分的所有数据都要小,
    然后再按此方法对这两部分数据分别进行快速排序,
    整个排序过程可以递归进行,
    以此达到整个数据变成有序序列
    :param a:list
    :return:sorted(a)
    """
    if a == []:
        return a
    else:
        a_first = a[0]
        a_less = quick_sort([i for i in a[1:] if i < a_first])
        a_more = quick_sort([j for j in a[1:] if j > a_first])
        result = a_less + [a_first] + a_more
        return result

堆排序

def heap_sort(a):
    """
    堆排序 时间复杂度 nlogn
    选择排序的一种,可以利用数组的特点快速定位指定索引的元素。
    堆分为大根堆和小根堆,是完全二叉树
    大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。
    在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,
    最大的值一定在堆顶
    :param a:list
    :return:sort(a)
    """
    import copy

    def heap_adjust(parent):
        child = 2 * parent + 1  ##  left child
        while child < len(heap):
            if child + 1 < len(heap):
                if heap[child + 1] > heap[child]:
                    child += 1  ##  right child
            if heap[parent] >= heap[child]:
                break
            heap[parent], heap[child] = heap[child], heap[parent]
            parent, child = child, 2 * child + 1

    heap, hlist = copy.copy(a), []
    for i in range(len(heap) // 2, -1, -1):
        heap_adjust(i)
    while len(heap) != 0:
        heap[0], heap[-1] = heap[-1], heap[0]
        hlist.insert(0, heap.pop())
        heap_adjust(0)
    return hlist

基数排序

def radix_sort(a):
    """
    基数排序 时间复杂度 o(LOGrB)
    透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用
    :param a:list
    :return:sort(a)
    """

    bucket, digit = [[]], 0
    while len(bucket[0]) != len(a):
        bucket = [[], [], [], [], [], [], [], [], [], []]
        for i in range(len(a)):
            num = (a[i] // 10 ** digit) % 10
            bucket[num].append(a[i])
        a.clear()
        for i in range(len(bucket)):
            a += bucket[i]
        digit += 1
    return a

归并排序

def merge_sort(a):
    """
    归并排序 时间复杂度 nlogn
    采用分治法(Divide and Conquer)的一个非常典型的应用。
    将已有序的子序列合并,得到完全有序的序列;
    即先使每个子序列有序,再使子序列段间有序。
    若将两个有序表合并成一个有序表,称为二路归并
    :param a:list
    :return:sorted(a)
    """
    def merge(left, right):
        result = []  ##  保存归并后的结果
        i = j = 0
        while i < len(left) and j < len(right):
            if left[i] <= right[j]:
                result.append(left[i])
                i += 1
            else:
                result.append(right[j])
                j += 1
        result = result + left[i:] + right[j:]  ##  剩余的元素直接添加到末尾
        return result

    ##  递归过程
    if len(a) <= 1:
        return a
    mid = len(a) // 2
    left = merge_sort(a[:mid])
    right = merge_sort(a[mid:])
    return merge(left, right)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值