7种排序算法的Python实现

概述

使序列成为一个按关键字有序的序列

稳定性:排序前 ki=kj(1<=i,j<=n,i!=j) && ij 排序方法不稳定

内排序:待排序的所有记录全部被放置在内存中。
外排序:整个排序过程需要在内外存之间多次交换数据。

7种排序算法的Python实现_第1张图片

直接插入

"""直接插入排序

思想
    将一个记录插入到有序的序列中

时间复杂度
    平均 o(n^2)

    最好 o(n),    比较n-1次
    最坏 o(n^2),  比较2+3+...+n次,交换3+4+...+n+1次
"""

array = [44, 32, 24, 23, 21, 18, 15, 10, 4, 2]
length = len(array)


def straight_insertion_sort():
    for i in range(2, length):
        if array[i] < array[i-1]:
            temp = array[i]  # 设置哨兵
            j = i-1
            while temp < array[j] and j >= 0:
                array[j], array[j+1] = array[j+1], array[j]
                j -= 1

            array[j+1] = temp


straight_insertion_sort()
print(array)

希尔排序

"""希尔排序

插入排序的改进版

思想
    将相聚某个“增量”(increment)的记录组成一个子序列,各子序列分别进行插入排序以使子序列基本有序。

    基本有序:小的关键字基本在前,大的关键字基本在后,不大不小的关键字基本在中间。

    增量序列的最后一个增量值必须为1,增量公式int(increment / 3 + 1)。

时间复杂度

"""

array = [44, 32, 24, 23, 21, 18, 15, 10, 4, 2]
length = len(array)


def shell_sort():
    increment = length

    while increment > 1:
        increment = int(increment / 3 + 1)  # 增量公式

        for i in range(increment, length, increment):
            if array[i] < array[i-increment]:
                temp = array[i]
                j = i - increment
                while temp < array[j] and j >= 0:
                    array[j], array[j + increment] = array[j + increment], array[j]
                    j -= increment

                array[j + increment] = temp


shell_sort()
print(array)

简单选择

"""简单选择排序

思想
    通过n-i次关键字比较,在n-i+1个元素中选出关键字最小(大)的记录,并和第i个记录交换。

时间复杂度
    平均 o(n^2)

    最好 o(n^2),比较n-1次
    最坏 o(n^2),比较n-1+n-2+...+1=n(n-1)/2次,交换n-1次

"""

array = [44, 32, 24, 23, 21, 18, 15, 10, 4, 2]
length = len(array)


def simple_selection_sort():
        for i in range(0, length-1):
            min = i

            for j in range(i+1, length):
                if array[min] > array[j]:
                    min = j

            if min is not i:
                array[min], array[i] = array[i], array[min]


simple_selection_sort()
print(array)    

堆排序

"""堆排序

思想
    1.将待排序序列构建成一个大(小)顶堆,此时整个序列的最大(小)值就是堆顶的根节点。
    2.将大(小)顶堆根节点与堆数组的末尾元素交换
    3.然后将除末尾以外的元素重新构造成一个大(小)顶堆
    4.如果堆的节点个数大于1,回到2

    堆是一个完全二叉树
    大顶堆:每个节点的值都大于或等于其左右孩子节点的值
    小顶堆:每个节点的值都小于或等于其左右孩子节点的值

"""

# 注意:这是完全二叉树,为方便运算(堆第i个节点的左孩子节点和右孩子节点位置分别是2i, 2i+1,),第一个元素一定要放在下标为1的位置
array = [0, 50, 10, 90, 30, 70, 40, 80, 60, 20]
length = len(array)-1


def heap_sort():
    # 构建堆
    for i in range(int(length/2), 0, -1):
        adjust(i, length)

    # 调整剩余元素为一个新的堆
    for i in range(length, 1, -1):
        array[1], array[i] = array[i], array[1]
        adjust(1, i-1)


def adjust(p, length):
    temp = array[p]
    i = 2*p
    while i <= length:
        if i+1 <= length and array[i] < array[i+1]:
            i += 1
        if temp > array[i]:
            break

        array[p] = array[i]

        p = i
        i *= 2

    array[p] = temp

heap_sort()
print(array)

冒泡排序

"""冒泡排序

思想
    两两比较相邻记录

时间复杂度
    平均 o(n^2)

    最好 o(n)     本身有序,比较n-1次
    最坏 o(n^2)   本身逆序,比较1+2+3+...+(n-1)=n(n-1)/2次,交换1+2+3+...+(n-1)=n(n-1)/2次

"""

array = [44, 32, 24, 23, 21, 18, 15, 10, 4, 2]
length = len(array)


def bubble_sort_1():
    """
    从后往前比较
    """
    i = 0
    while i < length-1:
        j = length-2
        while j >= i:
            if array[j] > array[j+1]:
                array[j], array[j + 1] = array[j + 1], array[j]  # python中交换简写

            j -= 1

        i += 1


def bubble_sort_2():
    """
    从前往后比较
    """
    i = 0
    while i < length-1:
        j = 0
        while j < length-1-i:
            if array[j] > array[j+1]:
                array[j], array[j + 1] = array[j + 1], array[j]  # python中交换简写

            j += 1

        i += 1


def bubble_sort_improved():
    """冒泡排序改进版

    当序列近似顺序时,避免不必要的比较,提高效率
    """
    i = 0
    flag = True
    while i < length-1 and flag:  # 当flag为False,退出循环
        flag = False

        j = length-2
        while j >= i:
            if array[j] > array[j+1]:
                array[j], array![j+1] = array[j+1],array[j]
                flag = True

            j -= 1

        i += 1

bubble_sort_2()
print(array)

快速排序


"""快速排序

思想
    1.选取序列中一个元素作为枢轴,让其左边的值都比它小,右边的值都比它大。
    2.将序列以枢轴为界限分割为左右两部分序列,如果分割后的序列的元素个数大于1,则执行步骤1。

"""
array = [32, 50, 10, 30, 30, 70, 40, 80, 60, 20]
length = len(array)


def quick_sort(f, r):
    if f >= r:
        return

    i = f
    j = r

    temp = array[f]
    while f < r:
        while f < r and temp <= array[r]:  # 从后向前比较
            r -= 1

        if f < r:
            array[f] = array[r]

        while f < r and temp >= array[f]:  # 从前向后比较
            f += 1

        if f < r:
            array[r] = array[f]

    array[r] = temp  # 此时r和j重合

    quick_sort(i, f-1)
    quick_sort(f+1, j)

quick_sort(0, 9)
print(array)

归并排序

"""归并排序

思想
    序列含有n个记录,可以看成n个有序子序列,每个子序列的长度为1,然后两两归并。

"""

array = [32, 50, 10, 30, 30, 70, 40, 80, 60, 20]
length = len(array)


def merging_sort(f, r):
    if f >= r:
        return

    mid = int((f+r)/2)

    merging_sort(f, mid)
    merging_sort(mid+1, r)
    merge(f, mid, r)


def merge(f, mid, r):
    temp = []
    i = f
    j = mid+1

    while i <= mid and j <= r:
        if array[i] <= array[j]:
            temp.append(array[i])
            i += 1
        else:
            temp.append(array[j])
            j += 1

    while i <= mid:
        temp.append(array[i])
        i += 1
    while j <= r:
        temp.append(array[j])
        j += 1

    for k in range (0, len(temp)):
        array[f+k] = temp[k]

merging_sort(0, 9)
print(array)

你可能感兴趣的:(算法)