it

ヒープ構造とは?データ構造の実装と操作(挿入操作:削除操作:ヒープ化:上向き・下向き調整:配列実装など)

当サイトでは記事内に広告を含みます

データ構造の学習でヒープ構造を学ぶ際に「理論はわかったけど、実際の実装はどうするの?」と疑問を感じる方も多いのではないでしょうか。

この記事では、ヒープ構造のデータ構造としての実装方法と主要な操作について、挿入・削除・ヒープ化・上向き調整・下向き調整・配列での実装まで詳しく解説しています。

ヒープの実装を理解することで、アルゴリズムの理解がより深まるでしょう。

ヒープ構造の実装方法と配列表現の基礎

それではまず、ヒープ構造の実装方法と配列表現の基礎について解説していきます。

ヒープ構造は完全二分木の性質を利用して、ポインタを使わずに配列(1次元のリスト)だけで効率よく実装できます。

配列のインデックスと木の親子関係を数式で対応させることで、追加メモリなしにヒープを実現できます。

配列によるヒープ実装の基本コード

Pythonでの最大ヒープの基本クラス実装:

class MaxHeap:

def __init__(self):

self.heap = []

def parent(self, i): return (i – 1) // 2

def left_child(self, i): return 2 * i + 1

def right_child(self, i): return 2 * i + 2

def size(self): return len(self.heap)

def get_max(self): return self.heap[0] if self.heap else None

ヒープ構造の各操作の概要

操作 英語名 計算量 概要
挿入 Insert / Push O(log n) 末尾に追加して上向き調整
最大値取り出し Extract Max / Pop O(log n) 根を削除して下向き調整
ヒープ化 Heapify O(n) 配列全体をヒープに変換
最大値参照 Peek O(1) 根を見るだけ(削除なし)

挿入操作と上向き調整の実装

続いては、挿入操作と上向き調整の実装を確認していきます。

挿入操作(Insert)の手順と実装

ヒープへの要素の挿入は「末尾に追加してから上向き調整(Sift Up)」という2ステップで行います。

挿入と上向き調整のPython実装:

def insert(self, value):

self.heap.append(value) # 末尾に追加

self._sift_up(len(self.heap) – 1) # 上向き調整

def _sift_up(self, i):

while i > 0 and self.heap[self.parent(i)] < self.heap[i]:

# 親より大きければ交換(最大ヒープ条件)

p = self.parent(i)

self.heap[i], self.heap[p] = self.heap[p], self.heap[i]

i = p

上向き調整は親ノードとの比較・交換を繰り返し、木の根に近づく方向に要素を移動させるため、最大でも木の高さO(log n)回の操作で完了します。

削除操作と下向き調整の実装

続いては、削除操作と下向き調整の実装を確認していきます。

最大値取り出し操作(Extract Max)の実装

削除と下向き調整のPython実装:

def extract_max(self):

if not self.heap: return None

max_val = self.heap[0]

self.heap[0] = self.heap[-1] # 末尾を根に移動

self.heap.pop() # 末尾を削除

if self.heap:

self._sift_down(0) # 根から下向き調整

return max_val

def _sift_down(self, i):

n = len(self.heap)

largest = i

l, r = self.left_child(i), self.right_child(i)

if l < n and self.heap[l] > self.heap[largest]: largest = l

if r < n and self.heap[r] > self.heap[largest]: largest = r

if largest != i:

self.heap[i], self.heap[largest] = self.heap[largest], self.heap[i]

self._sift_down(largest)

ヒープ化(Build Heap)の実装

既存の配列を最大ヒープに変換する「ヒープ化(Build Heap)」は、最後の内部ノード(インデックス(n//2)-1)から根に向かって順に下向き調整を適用することでO(n)で実現できます。

1要素ずつ挿入するO(n log n)の方法よりも、このヒープ化はO(n)の計算量で完了するためヒープソートなどで重要な最適化となっています。

まとめ

この記事では、ヒープ構造のデータ構造としての実装方法と主要な操作について、挿入・削除・ヒープ化・上向き下向き調整の実装コードとともに詳しく解説しました。

ヒープ構造は配列1本で完全二分木を表現し、O(log n)の効率的な挿入・削除とO(1)の最大値参照を実現する非常に実用的なデータ構造です。

今回の実装例を参考に、ヒープ構造をコードで実際に書いて理解を深めてみてください。