数据结构——排序

冒泡排序

稳定 时间复杂度O(N^2)  空间复杂度O(1)


def bubble_sort(lst):
    if len(lst) < 2:
        return

    # 最后一次交换的下标, 每经过一次便利,后面有序区至少多增加一位
    last_change_index = len(lst) - 1

    for i in range(len(lst) - 1):
        print(i, last_change_index)
        # 标记在一轮遍历中是否发生了交换,如果一次也没有发生交换,则元素已经整体有序
        is_change = False
        for j in range(last_change_index):
            if lst[j] > lst[j + 1]:
                lst[j], lst[j + 1] = lst[j + 1], lst[j]
                last_change_index = j
                is_change = True
        print(lst)
        if is_change is False:
            break


if __name__ == '__main__':
    # lst = [9, 2, 4, 1, 5, 3, 7, 6, 8, 0]
    lst = [1, 0, 2, 3, 4, 5, 6, 7, 8, 9]
    bubble_sort(lst)
    print(lst)

 


插入排序

稳定 时间复杂度O(N^2)  空间复杂度O(1)


def insert_sort(lst):
    if len(lst) < 2:
        return
    # 默认0位置上元素为有序区,从1位置开始遍历,插入有序区中
    for i in range(1, len(lst)):
        for j in range(i, 0, -1):
            # 如果小于有序区最后一个元素,则进行交换,进行下一轮比较,如果大于等于最后一个元素,该元素不用交换也达到有序,直接break,开始插入下一个元素
            if lst[j] < lst[j - 1]:
                lst[j - 1], lst[j] = lst[j], lst[j - 1]
            else:
                break


if __name__ == '__main__':
    lst = [9, 2, 4, 1, 5, 3, 7, 6, 8, 0]
    insert_sort(lst)
    print(lst)

 


选择排序

不稳定 时间复杂度O(N^2)  空间复杂度O(1)


def selection_sort(lst):
    if len(lst) < 2:
        return
    # 遍历整个数组,找到最小的元素,然后与0位置元素交换,再遍历剩下的元素,寻找第二小的元素放在1位置上,以此类推
    for i in range(len(lst)-1):
        min_index = i
        for j in range(i+1, len(lst)):
            if lst[min_index] > lst[j]:
                min_index = j
        lst[i], lst[min_index] = lst[min_index], lst[i]


if __name__ == '__main__':
    lst = [9, 2, 4, 1, 5, 3, 7, 6, 8, 0]
    selection_sort(lst)
    print(lst)

 


归并排序

稳定 时间复杂度O(NlogN)  空间复杂度O(NlogN


def merge_sort(lst):
    if len(lst) < 2:
        return lst

    mid = int(len(lst)/2)
    return merge(merge_sort(lst[0:mid]), merge_sort(lst[mid:]))


def merge(left, right):
    temp = []
    while left and right:
        if left[0] < right[0]:
            temp.append(left.pop(0))
        else:
            temp.append(right.pop(0))
    if len(left) > 0:
        temp.extend(left)
    if len(right) > 0:
        temp.extend(right)
    return temp


if __name__ == '__main__':
    lst = [9, 2, 4, 1, 5, 3, 7, 6, 8, 0]
    print(merge_sort(lst))

 


快速排序

不稳定 时间复杂度O(NlogN)  空间复杂度O(N)


 

import random

"""
首先随机一个位置的数作为主元,然后将它与最后一个位置的元素进行交换,交换以后将数组进行分区,
小于主元的数放在左边,等于的数放中间,大于的数放右边,分区过程中,默认小于区开始位置less等于left-1,
大于区开始位置more等于right,从left位置元素开始遍历,如果小于主元即right位置上的元素,则将less加一,
然后将left位置元素与less位置元素交换,交换以后将left值加一,开始下一轮比较;如果left位置元素大于主元,
则more加一,然后交换left位置与more位置元素,因为交换以后不知道交换到left位置more位置元素的大小,所以left不变,
继续下一次比较;如果left位置元素等于主元,则left加一,继续一轮比较。当left值等于more值时,停止比较,将right位置
上的元素与more位置上的元素交换,达到小于主元的数放左边,等于放中间,大于放右边
"""


def quick_sort(lst, left, right):
    if len(lst) < 2:
        return

    if left < right:
        pivot = random.randint(left, right)
        lst[pivot], lst[right] = lst[right], lst[pivot]
        border = partition(lst, left, right)
        quick_sort(lst, left, border[0])
        quick_sort(lst, border[1], right)


def partition(lst, left, right):
    less = left - 1
    more = right
    while left < more:
        if lst[left] < lst[right]:
            less += 1
            lst[less], lst[left] = lst[left], lst[less]
            left += 1
        elif lst[left] > lst[right]:
            more -= 1
            lst[left], lst[more] = lst[more], lst[left]
        else:
            left += 1

    lst[more], lst[right] = lst[right], lst[more]
    return [less, more+1]


if __name__ == '__main__':
    lst = [9, 2, 4, 1, 5, 3, 7, 6, 8, 0]
    quick_sort(lst, 0, 9)
    print(lst)

堆排序

不稳定 时间复杂度O(NlogN)   空间复杂度O(1)


"""
首先将数组构建成大顶堆,每个元素的父亲节点的下标值为(index-1)/2,左右孩子节点的下标值分别为
2*index+1,2*index+2,从0号位元素开始插入构建大根堆,只要他比他的父亲节点大就交换位置。构建好
大根堆以后,就进行heapify操作,将index号位元素与最后一个元素交换,因为时大根堆,所以index号位置元素是
最大的元素,然后把0~N-1位置的元素重新构造成大根堆,首先查找index号位置左右孩子节点的最大值,如果不比
index号位置元素大,则直接退出循环,如果比index号位置元素大,则交换,然后将index值改为左右孩子节点值的
最大下标,继续下一次的比较
"""


def heap_sort(lst):
    if len(lst) < 2:
        return

    for i in range(len(lst)):
        heap_insert(lst, i)

    size = len(lst) - 1
    lst[0], lst[size] = lst[size], lst[0]
    while size > 0:
        heapify(lst, 0, size)
        size -= 1
        lst[0], lst[size] = lst[size], lst[0]


def heap_insert(lst, index):
    father_index = int((index-1) / 2)
    while lst[index] > lst[father_index]:
        lst[index], lst[father_index] = lst[father_index], lst[index]
        index = father_index
        father_index = int((index-1) / 2)


def heapify(lst, index, size):
    left = 2 * index + 1
    while left < size:
        largest = [left, left + 1][(left + 1) < size and lst[left] < lst[left + 1]]
        if lst[index] >= lst[largest]:
            break
        lst[index], lst[largest] = lst[largest], lst[index]
        index = largest
        left = 2 * index + 1


if __name__ == '__main__':
    lst = [9, 2, 4, 1, 5, 3, 7, 6, 8, 0]
    heap_sort(lst)
    print(lst)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值