python中的堆排序模块heapq本身不支持自定义比较函数,可以通过重写对象的__lt__方法的方式来实现自定义比较函数。
__lt__对应<,当对象之间用<比较大小的时候,就会调用__lt__方法。同样的>会调用__gt__方法,在只重写了__lt__方法的时候,__gt__会对__lt__结果取反。但是当比较相等的时候,二者的结果是相等的。
import heapq
class P():
def __init__(self,a,b):
self.a = a
self.b = b
def __lt__(self, other):
if self.b<other.b:
return True
else:
return False
a = P(3,1)
b = P(2,3)
c = P(10,0)
d = P(3,1)
print(a>d)
print(a<d)
print(a<b)
print(a<c)
False
False
True
False
在heapq模块的内部,上浮和下沉的比较就是通过对象的<比较实现的:
def _siftdown(heap, startpos, pos):
newitem = heap[pos]
# Follow the path to the root, moving parents down until finding a place
# newitem fits.
while pos > startpos:
parentpos = (pos - 1) >> 1
parent = heap[parentpos]
if newitem < parent:
heap[pos] = parent
pos = parentpos
continue
break
heap[pos] = newitem
对于上面的类P的实例对象希望通过比较它的b属性建立堆排序。
import heapq
class P():
def __init__(self,a,b):
self.a = a
self.b = b
def __lt__(self, other):
if self.b<other.b:
return True
else:
return False
def p(self):
print(self.a,self.b)
a = P(3,1)
b = P(2,3)
c = P(10,0)
d = P(3,1)
h = []
heapq.heappush(h,a)
heapq.heappush(h,b)
heapq.heappush(h,c)
heapq.heappop(h).p()
10 0