【C言語】ヒープソートとは?仕組みや実装方法を解説

目次から探す

ヒープソートの概要

ヒープソートとは

ヒープソートは、効率的なソートアルゴリズムの一つです。

データを二分木の形で表現することで、データの整列を行います。

ヒープソートは、平均・最悪時間計算量ともにO(n log n)であり、安定なソートアルゴリズムとして知られています。

ヒープソートの特徴

ヒープソートの特徴は以下の通りです。

  • ソート対象のデータを二分木の形で表現するため、データの整列に際して追加のメモリ領域を必要としません。
  • ヒープソートは比較に基づくソートアルゴリズムであり、データの交換が頻繁に行われるため、データの移動回数が多いです。

ヒープソートの実装方法

ヒープの構築

ヒープソートを行うためには、まずヒープを構築する必要があります。

ヒープの構築は以下の手順で行います。

  1. ソート対象のデータを配列に格納します。
  2. 配列をヒープとして扱うために、配列の要素を二分木の形に整理します。
  3. ヒープを構築するために、配列の要素を順番に見ていき、親ノードと子ノードの大小関係を確認します。
  4. 親ノードと子ノードの大小関係が逆転している場合は、要素を交換します。
  5. 全ての要素について大小関係の確認と交換を行い、ヒープを構築します。

ヒープソートの実装例

以下に、ヒープソートの実装例を示します。

#include <stdio.h>
// 配列の要素を交換する関数
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}
// ヒープを構築する関数
void buildHeap(int arr[], int n, int i) {
    int largest = i; // 親ノード
    int left = 2 * i + 1; // 左の子ノード
    int right = 2 * i + 2; // 右の子ノード
    // 左の子ノードが親ノードより大きい場合
    if (left < n && arr[left] > arr[largest]) {
        largest = left;
    }
    // 右の子ノードが親ノードまたは左の子ノードより大きい場合
    if (right < n && arr[right] > arr[largest]) {
        largest = right;
    }
    // 親ノードと子ノードの大小関係が逆転している場合
    if (largest != i) {
        swap(&arr[i], &arr[largest]);
        buildHeap(arr, n, largest);
    }
}
// ヒープソートを行う関数
void heapSort(int arr[], int n) {
    // ヒープを構築する
    for (int i = n / 2 - 1; i >= 0; i--) {
        buildHeap(arr, n, i);
    }
    // ヒープから要素を取り出し、ソートする
    for (int i = n - 1; i >= 0; i--) {
        swap(&arr[0], &arr[i]);
        buildHeap(arr, i, 0);
    }
}
int main() {
    int arr[] = { 12, 11, 13, 5, 6, 7 };
    int n = sizeof(arr) / sizeof(arr[0]);
    heapSort(arr, n);
    printf("ソート結果:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    return 0;
}

上記の実装例では、配列をヒープソートするために、buildHeap関数でヒープを構築し、heapSort関数でヒープソートを行っています。

最後に、ソート結果を表示しています。

ヒープソートの利点と欠点

ヒープソートの利点

  • ヒープソートは、データの整列に際して追加のメモリ領域を必要としないため、メモリ使用量が少ないです。
  • 平均・最悪時間計算量がO(n log n)であり、効率的なソートアルゴリズムです。

ヒープソートの欠点

  • ヒープソートは比較に基づくソートアルゴリズムであり、データの交換が頻繁に行われるため、データの移動回数が多いです。
  • ヒープソートは安定なソートアルゴリズムではありません。

同じ値を持つ要素の順序が保持されない場合があります。

ヒープソートは、データの整列に際して追加のメモリ領域を必要としないため、ソート対象のデータが大きい場合やメモリ使用量を抑えたい場合に適しています。

また、ヒープソートは比較に基づくソートアルゴリズムであるため、ソート対象のデータが大きい場合でも効率的にソートすることができます。

ただし、ヒープソートは安定なソートアルゴリズムではないため、同じ値を持つ要素の順序が保持されない場合があります。

目次から探す