C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で最大ヒープ(Max Heap)を実装する方法とサンプルコード

二分ヒープ(Binary Heap)とは、完全二分木の構造を持ち、最小ヒープ(Min Heap)または最大ヒープ(Max Heap)のいずれかの性質を満たすデータ構造です。最大二分ヒープでは、ルートに位置するキーが、ヒープ内に存在するすべてのキーの中で最大値でなければなりません。この性質は、二分木内のすべてのノードに対して再帰的に成り立つ必要があります。最小二分ヒープも同様に、親ノードが子ノード以下になるという対称的な性質を持ちます。

アルゴリズム

max_heap 関数

Begin
    Declare function max_heap ()
      Declare j, t of the integer datatype.
      Initialize t = a[m].
      j = 2 * m;
      while (j <= n) do
          if (j < n && a[j+1] > a[j]) then
            j = j + 1
          if (t > a[j]) then
            break
          else if (t <= a[j]) then
            a[j / 2] = a[j]
            j = 2 * j
      a[j/2] = t
      return
End.

build_maxheap 関数

Begin
    Declare function build_maxheap(int *a,int n).
      Declare k of the integer datatype.
      for(k = n/2; k >= 1; k--)
          Call function max_heap(a,k,n)
End.

C++による実装例

以下は、配列から最大ヒープを構築する完全なC++プログラムです。ユーザーから要素数と各要素を入力として受け取り、build_maxheap関数によってヒープ化した結果を出力します。

#include <iostream>
using namespace std;
void max_heap(int *a, int m, int n) {
    int j, t;
    t = a[m];
    j = 2 * m;
    while (j <= n) {
       if (j < n && a[j+1] > a[j])
          j = j + 1;
       if (t > a[j])
          break;
       else if (t <= a[j]) {
          a[j / 2] = a[j];
          j = 2 * j;
       }
    }
    a[j/2] = t;
    return;
}
void build_maxheap(int *a,int n) {
    int k;
    for(k = n/2; k >= 1; k--) {
       max_heap(a,k,n);
    }
}
int main() {
    int n, i;
    cout<<"enter no of elements of array\n";
    cin>>n;
    int a[30];
    for (i = 1; i <= n; i++) {
       cout<<"enter elements"<<" "<<(i)<<endl;
       cin>>a[i];
    }
    build_maxheap(a,n);
    cout<<"Max Heap\n";
    for (i = 1; i <= n; i++) {
       cout<<a[i]<<endl;
    }
}

実行結果

このプログラムを実行し、5つの要素「7, 6, 2, 1, 4」を入力した場合の出力例です。最大値である7が先頭に配置され、ヒープの性質が満たされていることが確認できます。

enter no of elements of array
5
enter elements 1
7
enter elements 2
6
enter elements 3
2
enter elements 4
1
enter elements 5
4
Max Heap
7
6
2
1
4

処理のポイント

  • max_heap関数: 指定された位置mにある要素を適切な位置まで下ろす「sift-down(下向き調整)」操作を行います。子ノードと比較しながら、ヒープの性質が保たれるまで要素を入れ替えていきます。
  • build_maxheap関数: 葉ノード以外の最後のノード(n/2番目)から順に根に向かってmax_heapを呼び出すことで、配列全体をO(n)の計算量で最大ヒープに変換します。
  1. 【C++】STLのset_symmetric_differenceで集合の対称差を実装するプログラム

    本記事では、C++の標準テンプレートライブラリ(STL)に含まれる set_symmetric_difference 関数を使って、2つの集合の「対称差」を求めるプログラムを紹介します。 対称差とは、2つの集合のうち「どちらか一方にだけ存在し、両方には存在しない」要素から構成される集合のことです。 主な集合演算の種類 和集合(Union):どちらか一方に含まれるすべての要素 積集合(Intersection):両方に共通して含まれる要素 対称差(Symmetric Difference / 排他的論理和 XOR):片方にのみ含まれる要素 差集合(Difference / 減算):一方から他方

  2. C++でグラフの隣接行列を実装する方法【サンプルコード付き解説】

    隣接行列とは グラフの隣接行列(Adjacency Matrix)とは、V×Vのサイズを持つ正方行列のことです。ここでVはグラフGの頂点数を表します。行列の行と列にはそれぞれ頂点が対応付けられ、頂点iから頂点jへの辺が存在する場合は、i行目・j列目の要素に1が格納されます(重み付きグラフの場合は、辺の重みなどの非ゼロの値が入ります)。辺が存在しない場合は0が格納されます。 なお、無向グラフの場合、辺は双方向につながりを持つため、隣接行列は必ず対称行列になります。つまり、adj[i][j]とadj[j][i]は常に同じ値となります。 隣接行列表現の計算量 空間計算量: 隣接行列にはO(V²)