博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python堆排序
阅读量:4220 次
发布时间:2019-05-26

本文共 2260 字,大约阅读时间需要 7 分钟。

#!coding=utf-8

交换函数,python中直接交换的引用,直接return 对方的引用即可

def swap(a,b):        return b,a

这个函数根据传进来的begin,按照一定规则可以实现将数组中的部分数”挂“到树上去,这个规则是父节点一定大于两个孩子节点

首先判断left<=end,树的结构我们都知道:已知父节点i,左孩子是2*i,右孩子是2*i+1,而实际排序中可能没有右孩子,除去第一个占位符,若数组中有14个元素,那么14/2 = 7, 这时只有左节点而没有右节点

left <= end,只是为了确定这个left节点是不是数组中的元素:不越界

def heap(arr,begin,end):        k=begin        left=2*k        while left<=end:                if left                        left+=1                        #print "left is : %s,k is : %s"%(left,k)                if arr[k]                        arr[k],arr[left]=swap(arr[k],arr[left])                else:                        break                k=left                left=left*2

建立堆的函数:来分析一下这个流程(假设这里有15个元素,从a[1] ~~ a[15])

  建立堆,第一次传进来的值是 15/2 = 7,按照上面代码比较14和15,大的那个孩子节点再和父节点7比较,两个if语句结束,完成了比较和交换,14*2 = 28,跳出循环,这时节点7是属于它那个三角中最大的数
  第二个数是6, 按照和上面一样的顺序比完,6位置数最大,12*2 > 15跳出循环,同理还有5(20) , 4(16) ,到3之后除了3变成最大,还会再比较一次 6,12 13处,之后2,还会比较一次4,1还会比较一次2
  这些多出来的比较其实是多余的(改进方法暂时不想写,大家知道是多余的就行了)
   我们只需要知道从7开始最大的依次是7,6,5,4,然后3,6 7找最大的是3,2,4 5最大的是2,之后再比较 1, 2 3这时候就是a[1]这个元素最大了
   经历完上面这个过程,那么建堆的同时,我们将最大的那个元素调到最上面(也就是树顶了)

def buildheap(arr,n):        i=n/2        while i>=1:                heap(arr,i,n)                i-=1

  可以看到,堆排序首先先用建堆,这个过程运行的同时得到最上面的元素a[1]最大,那么,我们就可以将最大的那个元素a[1]放到数组的最后一位a[15],之后无论其他元素大小怎么样,总之a[15]成了最大的那个元素

  那么剩下的就是一直执行类似建堆的过程了

  经过上面那个过程可知:每一次最顶上的元素是最大的,我们将其换到末尾元素,末尾元素下表减1,这样一直到2,那么这个就变成了一个从小到达的有序数组了

def heapsort(arr,n):        buildheap(arr,n)        num=n        while num>1:                arr[1],arr[num]=swap(arr[1],arr[num])                num-=1                heap(arr,1,num)if __name__=='__main__':        arr1=[]        myfile=open('num.txt')        str=myfile.read()        for each in str.split():                each=int(each)                arr1.append(each) #  这里是我们构造了一个新的数组,第一个元素a[0]是占位符        mylen=len(arr1)        print arr1        duiarr=[0]*16        index=1        while index<=mylen:                duiarr[index]=arr1[index-1]                index+=1        print "\n"        heapsort(duiarr,mylen)        print duiarr

 

运行结果如下所示:
这里写图片描述

主要还是看分析建堆过程,我之前一直以为这个代码是没有问题的,但是仔细去尝试,发现了代码中貌似是有一些多余的步骤,希望看过的朋友有意见随时指出来,代码仅供参考

还有一点坑爹的地方,开头我写的swap只是返回两个交换的引用,而没有执行进行交换,需要赋值才能使用,发现的时候我瞬间蒙逼了….希望以后不要再犯这种低级错误

不知道为什么有些代码显示不出来,还是给一张图片吧,如下:
这里写图片描述

你可能感兴趣的文章
自定义Struts2中的ActionErrors
查看>>
windows xp 系统CMD命令大全
查看>>
控制Highcharts中x轴和y轴坐标值的密度
查看>>
xampp下Apache + Tomcat 集群配置的简单介绍(with sticky session)
查看>>
xampp(Apache + Tomcat)与主机的域名绑定
查看>>
增加windows下Tomcat运行时的内存
查看>>
tomcat群集中session共享的几个方案
查看>>
查看windows的开关机日志
查看>>
查找google谷歌北京IP地址的方法
查看>>
chrome的异常Uncaught ReferenceError: xl_chrome_menu is not defined
查看>>
Java不使用web容器,发布WebService应用
查看>>
大运动量的体能训练之后,如何迅速恢复体力?
查看>>
js+css 简单的高亮选中对象
查看>>
只长肌肉 不长脂肪——教你精确制导增肌餐
查看>>
转:解决mysql锁表终极方法
查看>>
MySQL 无法退出命令行中的SQL输入模式
查看>>
show engine innodb status 详解(转 )
查看>>
有氧运动和无氧运动 的能量消耗问题
查看>>
力量训练
查看>>
乱码问题!Eclipse 的控制台console必须用GBK编码。【转载】
查看>>