线性代数(Gelbert)的复习已经写到复习三了,不过依然不保证进度。写这篇一则是好久没更新了;二是表示一下,虽然开了新的数学坑,但是说过的复习部分我还是没有放弃的。
最近为了能对大数据平台的运行情况做一些细致的监控,写了不少抓取运行情况日志的脚本。之前都是我自己看,就一直乱着来的。现在要展现了,不能靠人眼排序了。于是今天下午写了个简单的优先级队列(注意:实现十分粗糙,虽然能满足我的需求,但是没有处理并发等等各种情况,也没优化过。如果有人想用,最好自己调整一下)。用二叉堆实现的,关于它的原理,可以参考我为了讲课整理的一些记录(其中的优先级队列部分):
https://github.com/saaavsaaa/saaavsaaa.github.io/blob/master/aaa/Structure_Abstract2.md直接看代码了。用了个全局的列表,其他就主要是插入和删除节点两个方法:
class PriorityQueue:heap_list = []def insert(self, e):self.heap_list.append(e) # 只是为了增加一个位置,可以append任何值self.percolateUp(len(self.heap_list) - 1, e)def pop(self):top = self.heap_list[0]self.heap_list[0] = self.heap_list[-1] # 用倒数第一个替代self.heap_list.pop() # heap_list = heap_list[0:-1]if (len(self.heap_list) > 0):self.percolateDown()return top
很明显其中起主要作用的就是 percolateUp 和 percolateDown 方法,看代码注释吧。其中的各种pass不要在意,主要是懒得删空格。
def percolateUp(self, index, value):j = 0while(index > 0):j = int((index - 1)/2) # index对应节点的直接前驱的秩if (value > self.heap_list[j]):self.heap_list[index] = self.heap_list[j] # 依次下移index = jpasselse:breakself.heap_list[index] = value # 没有依次更新,省几次交换pass
def percolateDown(self):index = 0last = self.heap_list[0] # 原末节点while index < len(self.heap_list):l_child = 2 * index + 1 # 左后继的秩r_child = 2 * (index + 1) # 右后继的秩sort_list = [(index, last)] # 这是为了找到当前节点和左右子节点中大的那个if l_child > len(self.heap_list) - 1:breakelse:sort_list.append((l_child, self.heap_list[l_child]))if r_child < len(self.heap_list):sort_list.append((r_child, self.heap_list[r_child]))passsort_list.sort(key=self.takeSecond, reverse=True) # 排序找出其中值比较大的largest_index = sort_list[0][0]if largest_index == index:break # 如果最大的就是当前节点,那么堆序性就满足了else:self.heap_list[index] = self.heap_list[largest_index]index = largest_index # 与左右子节点中大的那个交换passpassself.heap_list[index] = last # 同为了少几次交换return index
测试插入:
from priority_queue import PriorityQueuepq = PriorityQueue()pq.insert(2)print(pq.display())pq.insert(5)print(pq.display())pq.insert(3)print(pq.display())pq.insert(4)print(pq.display())pq.insert(1)print(pq.display())pq.insert(6)print(pq.display())pq.insert(5)print(pq.display())pq.insert(6)print(pq.display())
输出:
[2][5, 2][5, 2, 3][5, 4, 3, 2][5, 4, 3, 2, 1][6, 4, 5, 2, 1, 3][6, 4, 5, 2, 1, 3, 5][6, 6, 5, 4, 1, 3, 5, 2]
测试出队:
while len(pq.display()) > 0:print(pq.pop())print(pq.display())
输出:
6[6, 4, 5, 2, 1, 3, 5]6[5, 4, 5, 2, 1, 3]5[5, 4, 3, 2, 1]5[4, 2, 3, 1]4[3, 2, 1]3[2, 1]2[1]1[]
公众号: