Python入门篇-数据结构堆排序Heap Sort

                                      作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.堆Heap

  堆是一个完全二叉树
  每个非叶子结点都要大于或者等于其左右孩子结点的值称为大顶堆
  每个非叶子结点都要小于或者等于其左右孩子结点的值称为小顶堆
  根结点一定是大顶堆中的最大值,一定是小顶堆中的最小值

二.大顶堆

  完全二叉树的每个非叶子结点都要大于或者等于其左右孩子结点的值称为大顶堆
  根结点一定是大顶堆中的最大值

三.小顶堆

  完全二叉树的每个非叶子结点都要小于或者等于其左右孩子结点的值称为小顶堆
  根结点一定是小顶堆中的最小值

四.构建完全二叉树

  待排序数字为30,,,,,,,,90.
  构建一个完全二叉树存放数据,并根据性质5对元素编号,放入顺序的数据结构中.
  构造一个列表为[,,,,,,,,,].

五.构建大顶堆 

1>.核心算法

  度数为2的结点A,如果它的左右孩子结点的最大值比它大的,将这个最大值和该结点交换.
  度数为1的结点A,如果它的左孩子的值大于它,则交换.
  如果结点A被交换到新的位置,还需要和其孩子结点重复上面的过程.

2>.起点结点的选择

  从完全二叉树的最后一个结点的双亲结点开始,即最后一层的最右边叶子结点的父结点开始.
  结点数为n,则起始结点的编号为n//2(性质5).

3>.下一个结点的选择

  从起始结点开始向左找其同层结点,到头后再从上一层的最右边结点开始继续向左逐个查找,直至根结点.

4>.大顶堆的目标

  确保每个结点的都比左右结点的值大.

5>.排序

  将大顶堆根结点这个最大值和最后一个叶子结点交换,那么最后一个叶子结点就是最大值,将这个叶子结点排除在待排序结点之外.
  从根结点开始(新的根结点),重新调整为大顶堆后,重复上一步.
  堆顶和最后一个结点交换,并排除最后一个结点.

 6>.代码实现

 #!/usr/bin/env python
#_*_coding:utf-8_*_
#@author :yinzhengjie
#blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
#EMAIL:y1053419035@qq.com import math def print_tree(array):
index = 1
depth = math.ceil(math.log2(len(array))) #因为补0了,不然应该是math.ceil(math.log2(len(array) + 1)
sep = " "
for i in range(depth):
offset = 2 ** i
print(sep * (2 **(depth - i -1)-1),end="")
line = array[index:index + offset]
for j,x in enumerate(line):
print("{:>{}}".format(x,len(sep)),end="")
interval = 0 if i == 0 else 2 ** (depth - i) -1
if j < len(line) - 1:
print(sep * interval,end="")
index += offset
print() #为了和编码对应,增加一个无用的0在首位
origin = [0,30,20,80,40,50,10,60,70,90]
total = len(origin) - 1 #初始化排序元素个数,即n
print(origin) print_tree(origin)
print_tree("=" * 50) def heap_adjust(n,i,array:list):
"""
调整当前结点(核心算法)
调整的节点的起点在n//2,保证所有的调整的结点都有孩子结点
:param n: 待比较数个数
:param i: 当前结点的下标
:param array:待排序的数据
:return:
"""
while 2 * i <= n:
#孩子结点判断2i位左孩子,2i+1为右孩子
lchile_index = 2 * i
max_child_index = lchile_index #n = 2i
if n > lchile_index and array[lchile_index +1] > array[lchile_index]: #n > 2i说明还有右孩子
max_child_index = lchile_index + 1 #n = 2i +1 #和子树的根结点比较
if array[max_child_index] > array[i]:
array[i],array[max_child_index] = array[max_child_index],array[i]
i = max_child_index #被比较后,需要判断是否需要调整
else:
break #构建大顶推,大根堆
def max_heap(total,array:list):
for i in range(total//2,0,-1):
heap_adjust(total,i,array)
return array print_tree(max_heap(total,origin))
print_tree("=" * 50) #排序
def sort(total,array:list):
while total > 1:
array[1],array[total] = array[total],array[1] #堆顶和最后一个结点交换
total -= 1
if total == 2 and array[total] >= array[total -1]:
break
heap_adjust(total,1,array)
return array print_tree(sort(total,origin))
print_tree(origin)

六.总结

是利用堆性质的一种选择排序,在堆顶选出最大值或者最小值
  时间复杂度.
  堆排序的时间复杂度为O(nlogn).
  由于堆排序对原始记录的排序状态并不敏感,因此它无论是最好、最坏和平均时间复杂度均为O(nlogn).

1>.空间复杂度

  只是使用了一个交换用的空间,空间复杂度就是O().

2>.稳定性

  不稳定的排序算法.

Python入门篇-数据结构堆排序Heap Sort的更多相关文章

  1. Python入门篇-数据结构树(tree)的遍历

    Python入门篇-数据结构树(tree)的遍历 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.遍历 迭代所有元素一遍. 二.树的遍历 对树中所有元素不重复地访问一遍,也称作扫 ...

  2. Python入门篇-数据结构树(tree)篇

    Python入门篇-数据结构树(tree)篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.树概述 1>.树的概念 非线性结构,每个元素可以有多个前躯和后继 树是n(n& ...

  3. 数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)

    堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排 ...

  4. Python入门篇-封装与解构和高级数据类型集合(set)和字典(dict)

    Python入门篇-封装与解构和高级数据类型集合(set)和字典(dict) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.封装和结构 #!/usr/bin/env pytho ...

  5. Python入门篇-基础数据类型之整型(int),字符串(str),字节(bytes),列表(list)和切片(slice)

    Python入门篇-基础数据类型之整型(int),字符串(str),字节(bytes),列表(list)和切片(slice) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Py ...

  6. Python入门篇-面向对象概述

    Python入门篇-面向对象概述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.语言的分类 面向机器 抽象成机器指令,机器容易理解 代表:汇编语言 面向过程 做一件事情,排出个 ...

  7. Python入门篇-高阶函数

    Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数  1>.First Class Object 函数在Python中是一等公民 函数也 ...

  8. Python入门篇-基础语法

    Python入门篇-基础语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编程基础 1>.程序 一组能让计算机识别和执行的指令. 程序 >.算法+ 数据结构= 程 ...

  9. Python入门篇-StringIO和BytesIO

    Python入门篇-StringIO和BytesIO 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringIO(用于文本处理) 1>.使用案例 #!/usr/bin ...

随机推荐

  1. Java 8并行流的性能陷阱

    并行化流被分成多个块,每个块独立处理,结果在最后汇总. CPU密集型代码如下: private long countPrimes(int max) {     return range(1, max) ...

  2. leetcode刷题系列(一) 26题 删除排序数组中的重复项

    题干 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示 ...

  3. socket-02

    # -- coding: utf-8 -- _author__ = "HuaQiang Yan" import socket def handle_request(client): ...

  4. Docker 容器内无法通过 HTTP 访问外网

    现象 内/外网 IP 和 域名 可以 ping 通 容器内无法访问宿主机所在内网及外网的 Web 服务(404) 通过 curl 查看返回头信息感觉是所有 Web 请求被中转到一个固定的 Nginx ...

  5. SQL Server 类似正则表达式的字符处理问题

    SQL Serve提供了简单的字符模糊匹配功能,比如:like, patindex,不过对于某些字符处理场景还显得并不足够,日常碰到的几个问题有: 1. 同一个字符/字符串,出现了多少次 2. 同一个 ...

  6. 长乐国庆集训Day1

    T1 统计数字 题目 [题目描述] 设 S(N ) 表示 N 的各位数字之和,如 S(484) = 4+8+4 = 16, S(22) = 2+2 = 4. 如果一个正整数满足 S(x*x) = S( ...

  7. 修改 Delphi 10.3.3 IDE 字体和字体大小

    Delphi 10.2.2 之前,可以通过 IDE视觉设置的系统注册表项 修改字体和字体大小,因为 Delphi 10.2.2 IDE增加了主题,主题包含了字体信息, 此方法失效了.对于高分辨率屏幕, ...

  8. python requests 超时与重试

    一 源起: requests模块作为python爬虫方向的基础模块实际上在日常实际工作中也会涉及到,比如用requests向对方接口url发送POST请求进行推送数据,使用GET请求拉取数据. 但是这 ...

  9. Oracle打印输出在控制台

    SET SERVEROUTPUT ON  --必须有,不然显示不出declare LN_C number(10,0):=0;begin DECLARE LS_STR1 VARCHAR2(200); - ...

  10. C# 8.0 中开启默认接口实现

    原文:C# 8.0 中开启默认接口实现 当你升级到 C# 8.0 和 .NET Core 3.0 之后,你就可以开始使用默认接口实现的功能了. 从现在开始,你可以在接口里面添加一些默认实现的成员,避免 ...