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

C++で最小ヒープから最大要素を効率的に求める方法

問題の概要

最小ヒープ(min-heap)が与えられたとき、その中に含まれる最大要素を見つけるプログラムを作成します。

入力として次のような最小ヒープが与えられたとします。

C++で最小ヒープから最大要素を効率的に求める方法

この場合、最大要素は 55 となります。

アルゴリズムの考え方

最小ヒープには重要な性質があります。

  • 親ノードは必ず子ノード以下の値を持つ

この性質から、次のように結論づけられます。

  • 葉以外のノード(内部ノード)は、少なくとも1つの子ノードより小さい値を持つため、最大要素になることはない
  • したがって、最大要素は必ず葉ノードの中に存在する

つまり、配列で表現されたヒープにおいて、インデックス n/2 以降(葉ノードに相当する部分)だけを走査すればよいことになります。

計算量

走査対象は要素数の約半分であるため、時間計算量は O(n)、追加のメモリ使用量は O(1) となります。

C++での実装例

#include <bits/stdc++.h>
using namespace std;

int getMaxElement(int *heap, int n) {
    // 葉ノードの先頭(n/2番目)を初期値とする
    int maxVal = heap[n / 2];
    for (int i = n / 2 + 1; i < n; ++i) {
        maxVal = max(maxVal, heap[i]);
    }
    return maxVal;
}

int main() {
    int heap[] = {15, 27, 22, 35, 29, 55, 48};
    int n = sizeof(heap) / sizeof(heap[0]);
    cout << "Maximum element = " << getMaxElement(heap, n) << endl;
    return 0;
}

実行結果

Maximum element = 55

まとめ

最小ヒープの性質「親 ≤ 子」を利用することで、探索範囲を葉ノードのみに限定でき、無駄な比較を省けます。全要素を走査する場合と比べて処理量を約半分に抑えられるのがポイントです。

  1. C++で行列の各列の最大要素を見つける方法

    行列が与えられたとき、その行列の各列の最大要素を見つけて出力するのが本記事の目的です。このタスクは非常にシンプルで、各列ごとに最大値を初期化し、列内のすべての要素を順に比較しながら最大値を更新していくだけです。それでは、理解を深めるために実際のコードを見ていきましょう。アルゴリズムの考え方基本的な手順は以下の通りです。列を表すインデックス i を 0 から cols-1 まで順に走査します。各列の処理を開始する際に、最大値をその列の先頭要素 mat[0][i] で初期化します。行を表すインデックス j を 1 から rows-1 まで走査し、mat[j][i] が現在の最大値より大きければ最大

  2. C++で最小ヒープ(Min Heap)を実装するプログラム:アルゴリズムとサンプルコードを解説

    二分ヒープ(Binary Heap)は完全二分木の一種で、「最小ヒープ(Min Heap)」または「最大ヒープ(Max Heap)」のいずれかとして構成されます。最大二分ヒープでは、根(ルート)のキーがヒープ内のすべてのキーの中で最大でなければならず、この性質は木のすべてのノードに対して再帰的に成立している必要があります。最小二分ヒープはその逆で、親ノードのキーが常に子ノードのキー以下であることが保証されるデータ構造です。 本記事では、C++を使って最小ヒープを構築するプログラムを、アルゴリズム・サンプルコード・実行結果とあわせてわかりやすく解説します。 アルゴリズム min_heap()