数据结构与算法之数据结构 堆最佳实践 斐波那契堆 / 合并优化

数据结构与算法阿木 发布于 2025-07-11 9 次阅读


摘要:

堆是一种重要的数据结构,广泛应用于各种算法中,如优先队列、最短路径算法等。本文将围绕堆数据结构,探讨斐波那契堆和合并优化两种最佳实践,以提升堆的性能。

一、

堆是一种特殊的树形数据结构,它满足堆性质:对于任意节点,其值不大于(或不小于)其子节点的值。堆分为最大堆和最小堆,本文主要讨论最大堆。堆在计算机科学中有着广泛的应用,如优先队列、堆排序等。传统的二叉堆在性能上存在一些局限性。本文将介绍斐波那契堆和合并优化两种最佳实践,以提升堆的性能。

二、斐波那契堆

斐波那契堆是一种基于斐波那契树的最优堆数据结构,由Michael L. Fredman、Robert Sedgewick、Daniel D. Sleator和Robert E. Tarjan于1986年提出。斐波那契堆具有以下特点:

1. 树的形状:斐波那契堆的节点数满足斐波那契数列,即F(n) = F(n-1) + F(n-2),其中F(0) = 0,F(1) = 1。斐波那契堆的树形结构使得其具有较好的性能。

2. 树的深度:斐波那契堆的树形结构使得其深度非常小,平均深度为O(log n)。

3. 树的形状:斐波那契堆的树形结构使得其具有较好的平衡性,减少了树的高度。

4. 操作时间复杂度:斐波那契堆支持以下操作,其时间复杂度如下:

- 插入:O(1)

- 删除最小元素:O(log n)

- 合并:O(1)

- 查找最小元素:O(1)

以下是一个简单的斐波那契堆实现:

python

class FibonacciHeapNode:


def __init__(self, key):


self.key = key


self.degree = 0


self.mark = False


self.parent = None


self.children = []

class FibonacciHeap:


def __init__(self):


self.min_node = None


self.count = 0

def insert(self, key):


node = FibonacciHeapNode(key)


if self.min_node is None:


self.min_node = node


else:


self.min_node = self._merge(self.min_node, node)


self.count += 1

def extract_min(self):


min_node = self.min_node


if min_node is not None:


if min_node.children:


for child in min_node.children:


self._merge(self.min_node, child)


self.min_node = self._remove(self.min_node)


self.count -= 1


return min_node.key

def _merge(self, a, b):


if a is None:


return b


if b is None:


return a


if a.key < b.key:


a.right = b


b.left = a


return a


else:


b.right = a


a.left = b


return b

def _remove(self, node):


if node.left is node:


return None


parent = node.parent


if parent:


if node == parent.left:


parent.left = node.right


else:


parent.right = node.right


node.left = node.right = node


node.parent = None


return node

def decrease_key(self, node, key):


if key > node.key:


raise ValueError("new key is greater than current key")


node.key = key


parent = node.parent


if parent and node.key < parent.key:


self._cut(node, parent)


self._cascading_cut(parent)


if node.key < self.min_node.key:


self.min_node = node

def _cut(self, node, parent):


parent.degree -= 1


node.left = node.right = node


node.parent = None


self._merge(self.min_node, node)

def _cascading_cut(self, node):


parent = node.parent


if parent:


if node.mark:


self._cut(node, parent)


self._cascading_cut(parent)


else:


node.mark = True

def merge(self, other_heap):


if other_heap.min_node is None:


return


if self.min_node is None:


self.min_node = other_heap.min_node


else:


self.min_node = self._merge(self.min_node, other_heap.min_node)


self.count += other_heap.count


三、合并优化

合并优化是针对二叉堆的一种优化方法,通过减少合并操作的时间复杂度来提升堆的性能。以下是合并优化的步骤:

1. 在合并两个堆时,先比较两个堆的最小元素,将较小的堆作为子堆插入到较大的堆中。

2. 在插入操作中,如果堆已满,则先进行一次删除操作,再进行插入操作。

以下是一个简单的合并优化实现:

python

class BinaryHeap:


def __init__(self):


self.heap = []

def insert(self, key):


self.heap.append(key)


self._sift_up(len(self.heap) - 1)

def extract_min(self):


if not self.heap:


raise IndexError("Heap is empty")


min_key = self.heap[0]


self.heap[0] = self.heap.pop()


self._sift_down(0)


return min_key

def _sift_up(self, index):


while index > 0:


parent_index = (index - 1) // 2


if self.heap[parent_index] < self.heap[index]:


self.heap[parent_index], self.heap[index] = self.heap[index], self.heap[parent_index]


index = parent_index


else:


break

def _sift_down(self, index):


while True:


left_child_index = 2 index + 1


right_child_index = 2 index + 2


smallest_index = index


if left_child_index < len(self.heap) and self.heap[left_child_index] < self.heap[smallest_index]:


smallest_index = left_child_index


if right_child_index < len(self.heap) and self.heap[right_child_index] < self.heap[smallest_index]:


smallest_index = right_child_index


if smallest_index == index:


break


self.heap[index], self.heap[smallest_index] = self.heap[smallest_index], self.heap[index]


index = smallest_index

def merge(self, other_heap):


for key in other_heap.heap:


self.insert(key)


四、总结

本文介绍了斐波那契堆和合并优化两种最佳实践,以提升堆的性能。斐波那契堆具有较好的平衡性和操作时间复杂度,而合并优化则通过减少合并操作的时间复杂度来提升堆的性能。在实际应用中,可以根据具体需求选择合适的数据结构和优化方法,以提高算法的效率。