栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

[硕.Love Python] BinomialHeap(B堆 & 二项堆)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[硕.Love Python] BinomialHeap(B堆 & 二项堆)

class Node(object):
    def __init__(self, data):
 self.data = data
 self.child = None
 self.left = None
 self.right = None
 self.degree = 0

    def __str__(self):
 return str(self.data)

    __repr__ = __str__

class BinomialHeap(object):
    MAX_DEGREE = 20

    def __init__(self):
 self.root = None

    def combine(self, heap):
 self._dlistCombine(self.root, heap.root)

 if heap.root.data < self.root.data:
     self.root = heap.root

    def insert(self, data):
 node = Node(data)

 if self.root is None:
     self.root = node
     self._initSiblingList(node)
 else:
     self._addSibling(self.root, node)
     if data < self.root.data:
  self.root = node

    def pop(self):
 if self.root is None:
     raise ValueError('pop from empty heap.')

 res = self.root.data
 children = self.root.child
 siblings = self._dlistDelete(self.root)

 self.root = self._rebuild(children, siblings)

 return res

    def _rebuild(self, children, siblings):
 if children is None and siblings is None:
     return None

 treeArr = [None] * BinomialHeap.MAX_DEGREE
 self._combineTrees(treeArr, children)
 self._combineTrees(treeArr, siblings)

 head = None
 treeIterator = iter(treeArr)

 for node in treeIterator:
     if node:
  break

 root = head = prev = node
 for node in treeIterator:
     if node:
  prev.right = node
  node.left = prev
  prev = node
  if node.data < root.data:
      root = node

 head.left = prev
 prev.right = head

 return root

    def _combineTrees(self, treeArr, head):
 if head is None:
     return 

 node = head
 while True:
     tmp = node
     node = node.right

     for i in xrange(tmp.degree, len(treeArr)):
  if treeArr[i] is None:
      break
  tmp = self._joinTree(tmp, treeArr[i])
  treeArr[i] = None
     else:
  raise Exception('max degree')
     treeArr[i] = tmp
     if node is head:
  break

    def _joinTree(self, tree1, tree2):
 if tree2.data < tree1.data:
     tree1, tree2 = tree2, tree1

 self._addChild(tree1, tree2)
 return tree1

    def _dlistInit(self, head):
 head.left = head.right = head

    def _dlistCombine(self, head1, head2):
 r1 = head1.right
 l2 = head2.left

 head1.right = head2
 head2.left = head1
 r1.left = l2
 l2.right = r1

    def _dlistInsert(self, head, node):
 node.left = head
 node.right = head.right 

 node.right.left = node
 head.right = node

    def _dlistDelete(self, node):
 if node.left is node:
     newHead = None
 else:
     node.left.right = node.right
     node.right.left = node.left
     newHead = node.right

 return newHead

    _initSiblingList = _dlistInit
    _addSibling = _dlistInsert

    def _addChild(self, parent, child):
 if parent.child is None:
     parent.child = child
     self._initSiblingList(child)
 else:
     self._addSibling(parent.child, child)
 parent.degree += 1

if __name__ == '__main__':
    from random import sample

    data = range(1, 100000)
    data1 = sample(data, 1000)
    data2 = sample(data, 20000)

    heap1 = BinomialHeap()
    map(heap1.insert, data1)

    for _ in xrange(100):
 print heap1.pop(),
    print

    heap2 = BinomialHeap()
    map(heap2.insert, data2)

    heap1.combine(heap2)
    print '-' * 80
    for _ in xrange(200):
 print heap1.pop(),
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/225934.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号