Python排序搜索基本算法之堆排序实例详解


Posted in Python onDecember 08, 2017

本文实例讲述了Python排序搜索基本算法之堆排序。分享给大家供大家参考,具体如下:

堆是一种完全二叉树,堆排序是一种树形选择排序,利用了大顶堆堆顶元素最大的特点,不断取出最大元素,并调整使剩下的元素还是大顶堆,依次取出最大元素就是排好序的列表。举例如下,把序列[26,5,77,1,61,11,59,15,48,19]排序,如下:

Python排序搜索基本算法之堆排序实例详解

基于堆的优先队列算法代码如下:

def fixUp(a): #在堆尾加入新元素,fixUp恢复堆的条件
  k=len(a)-1
  while k>1 and a[k//2]<a[k]:
    a[k//2],a[k]=a[k],a[k//2]
    k=k//2
def fixDown(a): #取a[1]返回的值,然后把a[N]移到a[1],fixDown来恢复堆的条件
  k=1
  N=len(a)-1
  while 2*k<=N:
    j=2*k
    if j<N and a[j]<a[j+1]:
      j+=1
    if a[k]<a[j]:
      a[k],a[j]=a[j],a[k]
      k=j
    else:
      break
def insert(a,elem):
  a.append(elem)
  fixUp(a)
def delMax(a):
  maxElem=a[1]
  N=len(a)
  if N<=1:
    print('There\'s none element in the list')
    return -1
  if N==2:
    return a[1]
  else:
    a[1]=a.pop()
    fixDown(a)
    return maxElem
data=[-1,] #第一个元素不用,占位
insert(data,26)
insert(data,5)
insert(data,77)
insert(data,1)
insert(data,61)
insert(data,11)
insert(data,59)
insert(data,15)
insert(data,48)
insert(data,19)
result=[]
N=len(data)-1
for i in range(N):
  print(data)
  result.append(delMax(data))
print(result)

fixUp函数用于向列表的尾部添加一个新的元素,然后调整成大顶堆;fixDown函数用于取出大顶堆最大的元素后,把列表尾部的元素放到堆顶位置,然后再调整成大顶堆;insert函数是每次插入一个新的元素并调整成为大顶堆;delMax函数把最大的元素返回出来并把剩下的元素调整成为大顶堆。

输出如下:

[-1, 77, 61, 59, 48, 19, 11, 26, 1, 15, 5]
[-1, 61, 48, 59, 15, 19, 11, 26, 1, 5]
[-1, 59, 48, 26, 15, 19, 11, 5, 1]
[-1, 48, 19, 26, 15, 1, 11, 5]
[-1, 26, 19, 11, 15, 1, 5]
[-1, 19, 15, 11, 5, 1]
[-1, 15, 5, 11, 1]
[-1, 11, 5, 1]
[-1, 5, 1]
[-1, 1]
[77, 61, 59, 48, 26, 19, 15, 11, 5, 1]

前面的输出是不断取出最大元素后的大顶堆,由于是完全二叉树,根据列表可以自己写出大顶堆的树形结构,就不在这里赘述,最后一行是排好序的列表。

下面是堆排序算法,代码如下:

def fixDown(a,k,n): #自顶向下堆化,从k开始堆化
  N=n-1
  while 2*k<=N:
    j=2*k
    if j<N and a[j]<a[j+1]: #选出左右孩子节点中更大的那个
      j+=1
    if a[k]<a[j]:
      a[k],a[j]=a[j],a[k]
      k=j
    else:
      break
def heapSort(l):
  n=len(l)-1
  for i in range(n//2,0,-1):
    fixDown(l,i,len(l))
  while n>1:
    l[1],l[n]=l[n],l[1]
    fixDown(l,1,n)
    n-=1
  return l[1:]
l=[-1,26,5,77,1,61,11,59,15,48,19] #第一个元素不用,占位
res=heapSort(l)
print(res)

输出如下:

[1, 5, 11, 15, 19, 26, 48, 59, 61, 77]
Python 相关文章推荐
Python中join和split用法实例
Apr 14 Python
python生成随机图形验证码详解
Nov 08 Python
python计算列表内各元素的个数实例
Jun 29 Python
Python pyinotify模块实现对文档的实时监控功能方法
Oct 13 Python
python安装pywin32clipboard的操作方法
Jan 24 Python
python从子线程中获得返回值的方法
Jan 30 Python
如何利用Anaconda配置简单的Python环境
Jun 24 Python
python 同时读取多个文件的例子
Jul 16 Python
python matplotlib如何给图中的点加标签
Nov 14 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
Feb 29 Python
Python通过两个dataframe用for循环求笛卡尔积
Apr 29 Python
Python 找出英文单词列表(list)中最长单词链
Dec 14 Python
基于Django contrib Comments 评论模块(详解)
Dec 08 #Python
Python数据分析中Groupby用法之通过字典或Series进行分组的实例
Dec 08 #Python
python在ubuntu中的几种安装方法(小结)
Dec 08 #Python
Python编程之gui程序实现简单文件浏览器代码
Dec 08 #Python
Python中的pygal安装和绘制直方图代码分享
Dec 08 #Python
python的unittest测试类代码实例
Dec 07 #Python
Python numpy 常用函数总结
Dec 07 #Python
You might like
mysql 全文搜索 技巧
2007/04/27 PHP
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
PHP无限分类(树形类)的深入分析
2013/06/02 PHP
php获取qq用户昵称和在线状态(实例分析)
2013/10/27 PHP
利用PHP实现开心消消乐的算法示例
2017/10/12 PHP
php实现网页上一页下一页翻页过程详解
2019/06/28 PHP
基于jQuery的自动完成插件
2011/02/03 Javascript
JS正则中的RegExp对象对象
2012/11/07 Javascript
js出生日期 年月日级联菜单示例代码
2014/01/10 Javascript
jQuery实现选中弹出窗口选择框内容后赋值给文本框的方法
2015/11/23 Javascript
分享几种比较简单实用的JavaScript tabel切换
2015/12/31 Javascript
javascript html5 canvas实现可拖动省份的中国地图
2016/03/11 Javascript
详解JS数据类型的值拷贝函数(深拷贝)
2017/07/13 Javascript
JavaScript html5 canvas实现图片上画超链接
2017/10/20 Javascript
JS改变页面颜色源码分享
2018/02/24 Javascript
webpack 样式加载的实现原理
2018/06/12 Javascript
微信小程序登录session的使用
2019/03/17 Javascript
layui实现下拉框三级联动
2019/07/26 Javascript
vue 实现购物车总价计算
2019/11/06 Javascript
原生js实现碰撞检测
2020/03/12 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
js将日期格式转换为YYYY-MM-DD HH:MM:SS
2020/09/18 Javascript
express异步函数异常捕获示例详解
2020/11/30 Javascript
读取本地json文件,解析json(实例讲解)
2017/12/06 Python
Python+OpenCV图片局部区域像素值处理详解
2019/01/23 Python
python3正则模块re的使用方法详解
2020/02/11 Python
Python post请求实现代码实例
2020/02/28 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
2020/06/27 Python
pycharm中选中一个单词替换所有重复单词的实现方法
2020/11/17 Python
H5最强接口之canvas实现动态图形功能
2019/05/31 HTML / CSS
Links of London官方网站:英国标志性的珠宝品牌
2017/04/09 全球购物
广州盈通面试题
2015/12/05 面试题
普通简短的个人自我评价
2014/02/15 职场文书
家庭贫困证明书(3篇)
2014/09/15 职场文书
教师个人考察材料
2014/12/16 职场文书
anaconda python3.8安装后降级
2021/06/11 Python