python 堆排序

# 二叉树的遍历# 对二叉树中的全部元素不重复的访问一遍# 广度优先遍历#   层序遍历#       从第一层开始,没一层从左至右遍历元素# 深度优先遍历# 假设树的根节点为D,左子树为L,右子树为R,且要求L必定在R以前,则有如下遍历方式:#   前序遍历:也叫先序遍历,也叫先根遍历,DLR#   中序遍历:也叫中根遍历,LDR#   后序遍历:也叫后根遍历,LRD# 遍历序列:将树中全部元素遍历一遍后,获得的元素的序列,将层次结构转换成了线性结构# 堆排序# 堆是一个彻底二叉树# 每一个非叶子结点的值都要大于或者等于其左右孩子结点的值,称为大顶堆# 每一个非叶子结点的值都要小于或者等于其左右孩子结点的值,称为小顶堆# 根结点必定是大顶堆中的最大值,必定是小顶堆中的最小值# 例子:构建一个彻底二叉树(序列 -> 彻底二叉树 -> 大顶堆 -> 排序 - > 大顶堆 -> 排序 ...)#   待排序数字为:30 20 80 40 50 10 60 70 90#   构建一个彻底二叉树存放数据,并根据性质5对元素编号,放入顺序的数据结构中#       性质5:按层依次编号#   构建一个列表为[0, 30, 20, 80, 40, 50, 10, 60, 70, 90]***#       0为补位,由于列表下表从0开始,想从1开始进行使用#   构建大顶堆的核心算法#       度数为2的结点A,若是它的左右孩子结点的最大值比它大,将这个最大值和该结点交换#       度数为1的结点A,若是它的左孩子的值比它大,则交换#       若是结点A被交换到新的位置,还须要和其孩子结点重复上面的过程#   构建大顶堆 - 起点结点的选择#       从彻底二叉树的最后一个结点的双亲结点开始,即最后一层的最右边叶子结点的父节点开始***#       结点数为n,则起始结点的编号n//2(性质5)#   构建大顶堆 - 下一个结点的选择#       从起始结点开始向左找其同层结点,到头后再从上一层的最右边结点开始继续向左逐个查找,直到根节点#       下一结点:n -> n-1 -> n-2 ... 1#   跟结点计算完毕后,若是有交换,则还须要向下对左右子树进行再次排序# 大顶堆的目标#       确保每一个结点的值都比左右结点的值大# 排序#   将大顶堆根结点这个最大值和最后一个叶子结点交换,那么最后一个叶子结点就是最大值,将这个叶子结点排除在待排序结点外#   从根结点开始(新的根结点),从新调整为大顶堆后,重复上一步# 将列表打印成树(堆排序辅助函数)import mathdef printTree(lst):    treeLen  = len(lst)    treeLay = math.ceil(math.log2(treeLen + 1)) # 树层数    index = 0    treeWidth = 2 ** treeLay - 1    # 树宽度    for i in range(treeLay):        for j in range(2**i):            print('{:^{}}'.format(lst[index], treeWidth), end=' ')            index += 1            if index >= treeLen:                break        treeWidth = treeWidth//2        print()lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]printTree(lst)# 调整当前节点def heap_adjust(n, i, array:list):  # array:list 表示array变量的类型是list    '''    调整当前节点核心算放    :param n: 待比较数字的个数    :param i: 当前节点的下标    :param array: 待排序数据    :return:None    '''    while 2 * i <= n:   # 性质5,=n只有左子树        # 孩子结点判断2i为左孩子,2i+1为右孩子        lChild_index = 2 * i        maxChild_index = lChild_index # n=2i        if n > lChild_index and array[lChild_index + 1] > array[lChild_index]:  # n>2i说明还有右孩子            maxChild_index = lChild_index + 1   # n=2i+1        # 和子树的根节点比较        if array[maxChild_index] > array[i]:            array[i], array[maxChild_index] = array[maxChild_index], array[i]   # 交换            i = maxChild_index # 被交换后,须要判断是否还须要调整        else:            break        printTree(array)        print('--------------------------')# 构建大顶堆def maxHeap(total, array:list):    for i in range(total//2, 0, -1):        heap_adjust(total, i, array)    # 调整当前结点    return arraytotal = 9origin = [0,30, 20, 80, 40, 50, 10, 60, 70, 90]print('maxHeap is ')printTree(maxHeap(total, origin))# 结论:第一层是最大值,第二层必定有个次大值
相关文章
相关标签/搜索