常用排序算法总结

实现稍微难点的三个算法:快排、归并、堆排序

快速排序

以下是一种写法(算法导论上是另一种写法,待补充)

def quickSort(data, start, end):
    i = start
    j = end
    # i与j重合,一次排序结束
    if i >= j:
        return
    # 设置最左边的数为基准值
    flag = data[start]
    while i < j:
        while i < j and data[j] >= flag:
            j -= 1
        # 找到右边第一个小于基准的数赋值给左边i(此时左边i被记录在flag中)
        data[i] = data[j]
        while i < j and data[i] <= flag:
            i += 1
        # 找到左边第一个大于基准的数赋值给右边的j
        data[j] = data[i]
    # 循环完后把flag值放到i所在位置
    data[i] = flag
    # print(data)
    # 除去i之外两段递归
    quickSort(data, start, i - 1)
    quickSort(data, i + 1, end)

if __name__ == "__main__":
    data = [6, 5, 8, 2, 3, 1]
    print(data)
    quickSort(data, 0, len(data) - 1)
    print(data)

冒泡排序

def bubbleSort(alist):
    n = len(alist)
    exchange = False
    for i in range(n-1, 0, -1):
        for j in range(0, i):
            if alist[j] > alist[j+1]:
                alist[j], alist[j+1] = alist[j+1], alist[j]
                exchange = True
        # 如果发现整个排序过程中没有交换,提前结束
        if not exchange:
            break
    return alist

选择排序

  • 选择排序是在冒泡排序的基础上优化的,提高了冒泡排序的性能
def selectionSort(alist):
    n = len(alist)

    for i in range(n - 1):
        # 寻找[i,n]区间里的最小值
        min_index = i
        for j in range(i+1, n):
            if alist[j] < alist[min_index]:
                min_index = j
        alist[i], alist[min_index] = alist[min_index], alist[i]
    return alist

插入排序

def insertionSort(blist):
    n = len(blist)
    for i in range(1, n):
    # 寻找a[i]合适的插入位置
        temp = blist[i]
        for j in range(i, 0, -1):
            if temp < blist[j-1]:
                blist[j] = blist[j-1]
            else:
                break
            blist[j-1] = temp
    print(blist)
    return blist

希尔排序

  • 希尔排序是在插入排序的基础上优化的,提高了插入排序的性能
def shell1Sort(data):
    step = len(data) // 2
    while step >= 1:
        print("当前增量是:", step)
        for i in range(step, len(data)):
            for j in range(i-step, -step, -step):
                if data[j] > data[j+step]:
                    data[j], data[j+step] = data[j+step], data[j]
        step = int(step/2)

归并排序

def merge_sort(nums):
    if len(nums) <= 1:
        return nums
    middle = len(nums) // 2
    left_num = nums[:middle]
    right_num = nums[middle:]
    return merge(merge_sort(left_num), merge_sort(right_num))

def merge(left_num, right_num):
    len_left = len(left_num)
    len_right = len(right_num)
    i = j = 0
    result = []
    # 比较left_num和left_right中的元素,按序添加到result中
    while i < len_left and j < len_right:
        if left_num[i] > right_num[j]:
            result.append(right_num[j])
            j += 1
        else:
            result.append(left_num[i])
            i += 1
    # 将j中的剩余元素添加到result中
    if i == len_left and j < len_right:
        for m in right_num[j:]:
            result.append(m)
    # 将i中的剩余元素添加到result中
    if j == len_right and i < len_left:
        for m in left_num[i:]:
            result.append(m)
    return result

堆排序(个人感觉算法很赞)

from collections import deque
# python中交换两个元素的位置
def swap(nums, i, j):
    nums[i], nums[j] = nums[j], nums[i]
    return nums

# 构造最大堆
def heap_adjust(nums, start, end):
    temp = nums[start]
    i = start
    j = start * 2
    while j <= end:
        if j < end and nums[j] < nums[j + 1]:
            j += 1
        if temp < nums[j]:
            nums[i] = nums[j]
            i = j
            j = i * 2
        else:
            break
    nums[i] = temp

# 堆排序
def heap_sort(nums):
    len_heap = len(nums) - 1
    len_mid_heap = len_heap // 2

    # 将序列调整为一个最大堆
    for i in range(len_mid_heap):
        heap_adjust(nums, len_mid_heap-i, len_heap)
    print(nums)

    # 将堆顶元素和堆末尾元素交换,将剩下元素调整为一个最大对
    for i in range(len_heap-1):
        swap(nums, len_heap-i, 1)
        heap_adjust(nums, 1, len_heap-i-1)

    print(nums)
    return list(nums)[1:]


def main():
    L = deque([50, 16, 30, 10, 60, 90, 2, 80, 70])
    L.appendleft(0)
    print(heap_sort(L))

参考资料

posted @ 2020-11-14 17:17  baishengguan  阅读(65)  评论(0编辑  收藏  举报