使用Python实现树形结构的斐波那契堆算法
斐波那契堆(Fibonacci Heap)是一种基于树形结构的优先队列,它是由斐波那契数列(Fibonacci Sequence)引出的一种堆数据结构,其主要特点是可以在插入和删除节点时保持时间复杂度为O(log n)。
斐波那契堆实际上是一组最小堆(Min Heap)的集合,其中每个最小堆都是一个二项堆(Binomial Heap),并且被组织成一种森林(Forest)形式。斐波那契堆的节点包含以下信息:
- key:节点的键值,用于比较和排序
- degree:节点的度数,即它的子节点的数量
- mark:用于标记节点是否失去过子节点
下面是斐波那契堆的Python实现代码,其中使用字符串"pidancode.com"和"皮蛋编程"作为范例:
class FibonacciHeap: class Node: def __init__(self, key): self.key = key self.parent = None self.child = None self.left = None self.right = None self.degree = 0 self.mark = False def __init__(self): self.min_node = None self.node_count = 0 def is_empty(self): return self.min_node is None def insert(self, key): new_node = self.Node(key) if self.min_node is None: self.min_node = new_node else: self.__link_nodes(new_node, self.min_node) if new_node.key < self.min_node.key: self.min_node = new_node self.node_count += 1 def find_min(self): if self.is_empty(): raise ValueError("Heap is empty") return self.min_node.key def delete_min(self): if self.is_empty(): raise ValueError("Heap is empty") old_min = self.min_node # 将old_min的子节点全部添加到根节点列表中 if old_min.child is not None: child_nodes = [old_min.child] node = old_min.child.right while node != old_min.child: child_nodes.append(node) node = node.right for child in child_nodes: self.__add_to_root_list(child) child.parent = None # 删除old_min self.__remove_from_root_list(old_min) if old_min == old_min.right: # 只有一个节点,删除后为空 self.min_node = None else: self.min_node = old_min.right self.__consolidate() self.node_count -= 1 return old_min.key def decrease_key(self, node, new_key): if new_key > node.key: raise ValueError("new key is greater than current key") node.key = new_key if node.parent is not None and node.key < node.parent.key: self.__cut_node(node) self.__cascading_cut(node.parent) if node.key < self.min_node.key: self.min_node = node def __add_to_root_list(self, node): node.left = node.right = node if self.min_node is None: self.min_node = node else: self.__link_nodes(node, self.min_node) def __remove_from_root_list(self, node): if node == node.right: self.min_node = None else: if node == self.min_node: self.min_node = node.right self.__unlink_nodes(node, node.right) def __link_nodes(self, node1, node2): node1.right = node2.right node2.right.left = node1 node2.right = node1 node1.left = node2 def __unlink_nodes(self, node1, node2): node1.right = node2 node2.left = node1 def __consolidate(self): A = [None] * self.node_count node = self.min_node while True: degree = node.degree while A[degree] is not None: other = A[degree] if node.key > other.key: node, other = other, node self.__link_nodes(other, node) A[degree] = None degree += 1 A[degree] = node node = node.right if node == self.min_node: break self.min_node = None for item in A: if item is not None: self.__add_to_root_list(item) def __cut_node(self, node): self.__remove_from_child_list(node.parent, node) node.parent.degree -= 1 self.__add_to_root_list(node) node.mark = False def __cascading_cut(self, node): parent = node.parent if parent is not None: if node.mark == False: node.mark = True else: self.__cut_node(node) self.__cascading_cut(parent) def __remove_from_child_list(self, parent, child): if parent.child == parent.child.right: parent.child = None elif parent.child == child: parent.child = child.right self.__unlink_nodes(child.left, child.right) def __str__(self): nodes = [] node = self.min_node while True: nodes.append(str(node.key)) node = node.right if node == self.min_node: break return ', '.join(nodes)
这个实现包含了斐波那契堆的常见操作,其中使用了双向链表来组织根节点列表和子节点列表。下面是使用这个实现创建斐波那契堆,并进行一些操作的例子:
heap = FibonacciHeap() heap.insert("pidancode.com") heap.insert("皮蛋编程") heap.insert("Fibonacci Heap") heap.insert("Python") heap.insert("algorithm") print(heap) # Python, 皮蛋编程, algorithm, pidancode.com, Fibonacci Heap print(heap.find_min()) # 'Python' heap.delete_min() print(heap) # pidancode.com, 皮蛋编程, algorithm, Fibonacci Heap heap.decrease_key(heap.min_node.right.right, "AAABBB") print(heap) # pidancode.com, 皮蛋编程, AAABBB, Fibonacci Heap heap.delete_min() print(heap) # 皮蛋编程, AAABBB, Fibonacci Heap
相关文章