python写几个排序算法

def maopao(data: list):
    """
    两两比较
    :param data:
    :return:
    """
    length = len(data)
    for i in range(length - 1):
        flag = True
        for j in range(length - 1 - i):
            if data[j] > data[j + 1]:
                data[j], data[j + 1] = data[j + 1], data[j]
                flag = False
        print(i, data)
        if flag:
            break


def choice(data: list):
    """
    对未排序的元素中选出最小值替换到当前位置
    :param data:
    :return:
    """
    length = len(data)
    for i in range(length - 1):
        min_index = i
        for j in range(i + 1, length):
            if data[j] < data[min_index]:
                min_index = j

        data[i], data[min_index] = data[min_index], data[i]
        print(i, data)


def insert(data: list):
    """
    从第二个元素开始,跟左边的所有元素比较,找到它比左边元素小的地方,把它从原位置插入到这个地方
    :param data:
    :return:
    """
    length = len(data)
    for i in range(1, length):
        # 找到合适的位置
        for j in range(i):
            if data[i] < data[j]:
                data.insert(j, data.pop(i))
        print(i - 1, data)


def quick(data: list):
    """
    从数组中选择一个元素称之为中轴元素,然后把数组中所有小于中轴元素的元素放在其左边,
    所有大于或等于中轴元素的元素放在其右边,显然,此时中轴元素所处的位置的是固定的,也就是说,我们无需再移动中轴元素的位置。
    从中轴元素那里开始把大的数组切割成两个小的数组(两个数组都不包含中轴元素),
    接着我们通过递归的方式,让中轴元素左边的数组和右边的数组也重复同样的操作,
    直到数组的大小为1,此时每个元素都处于有序的位置。
    :param data:
    :return:
    """
    if not data:
        return []
    length = len(data)
    tmp = data[0]

    small = []
    big = []

    i = 0
    times = 0
    while times < length:
        if data[i] < tmp:
            small.append(data.pop(i))
        elif data[i] > tmp:
            big.append(data.pop(i))
        else:
            i += 1
        times += 1
    return quick(small) + data + quick(big)


def mergesort(seq: list):
    """
    先把一个序列从中间分开,然后把两个序列再次分开,直到只有一个元素为止,
    然后两两排序合并,再四四排序合并,再八八排序合并...最后合并到一起
    """

    def merge(left, right):
        result = []  # 新的已排序好的列表
        i = 0  # 下标
        j = 0
        # 对两个列表中的元素 两两对比。
        # 将最小的元素,放到result中,并对当前列表下标加1
        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 += left[i:]
        result += right[j:]
        return result

    if len(seq) <= 1:
        return seq
    mid = len(seq) // 2  # 将列表分成更小的两个列表
    # 分别对左右两个列表进行处理,分别返回两个排序好的列表
    left_list = mergesort(seq[:mid])
    right_list = mergesort(seq[mid:])
    # 对排序好的两个列表合并,产生一个新的排序好的列表
    return merge(left_list, right_list)


def heapsort(seq: list):
    def make_heap(data: list):
        """
        把数组变成一个大顶堆.
        :param data:
        :return:
        """
        length = len(data)

        # 遍历所有的父结点位置,从后往前遍历
        for parentNode in range(length // 2 - 1, -1, -1):
            while True:
                # 当前节点的左子节点
                sonNode = parentNode * 2 + 1
                if sonNode >= length:
                    break
                # sonNode+1 是右子节点
                # 若右子节点在最后一个节点之前,并且右子节点比左子节点大,把孩子指针移到右子节点上,这样就可以交换更大的数
                if (sonNode + 1 <= length - 1) and (data[sonNode + 1] > data[sonNode]):
                    sonNode += 1
                if data[parentNode] < data[sonNode]:
                    data[sonNode], data[parentNode] = data[parentNode], data[sonNode]
                else:
                    break

    # 依次取出第0项,然后重建堆
    result = []
    length = len(seq)
    for end in range(length):
        make_heap(seq)
        result.append(seq.pop(0))
    return result


if __name__ == '__main__':
    import random

    source = [random.randint(0, i) for i in range(5, 999)]
    # source = [6, 5, 7, 2, 11, 4, 10, 2, 5, 3, 1, 9, 6, 4]
    print('-', source)

    # maopao(source)
    # choice(source)
    # insert(source)
    # print(mergesort(source))
    sorts = source.copy()
    sorts.sort(reverse=True)
    aa = heapsort(source)
    print(sorts == aa)

posted @ 2020-12-09 18:28  rm-rf*  阅读(94)  评论(0编辑  收藏  举报