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

C++で学ぶ配列の並べ替え – 最小値・最大値・2番目に小さい値・2番目に大きい値を交互に配置する方法

配列が与えられたとき、最初の要素を最小値、2番目の要素を最大値、3番目の要素を2番目に小さい値、4番目の要素を2番目に大きい値…というように、小さい値と大きい値を交互に並べ替えることを考えます。具体例は以下のとおりです。

入力 : arr[ ] = { 13, 34, 30, 56, 78, 3 }
出力 : { 3, 78, 13, 56, 34, 30 }
説明 : 配列は { 1番目に小さい値, 1番目に大きい値, 2番目に小さい値, 2番目に大きい値, 3番目に小さい値, 3番目に大きい値 } の順に並べ替えられます

入力 : arr[ ] = { 2, 4, 6, 8, 11, 13, 15 }
出力 : { 2, 15, 4, 13, 6, 11, 8 }

解決策へのアプローチ

この問題は、最小要素と最大要素をそれぞれ指す2つの変数「x」と「y」を使うことで解決できます。ただし、そのためには配列がソート済みである必要があるため、まず元の配列を昇順にソートします。続いて、同じサイズの新しい空の配列を用意し、並べ替えた結果をそこに格納していきます。配列を先頭から走査し、現在のインデックス i が偶数の場合は arr[x](最小側)の要素を新しい配列に格納して x を1増やし、i が奇数の場合は arr[y](最大側)の要素を格納して y を1減らします。この処理を y が x より小さくなるまで繰り返します。

この手法の計算量は、ソートに O(n log n)、並べ替えの走査に O(n) となるため、全体の計算量は O(n log n) となります。

C++での実装例

#include <bits/stdc++.h>
using namespace std;
int main () {
    int arr[] = { 2, 4, 6, 8, 11, 13, 15 };
    int n = sizeof (arr) / sizeof (arr[0]);

    // 並べ替えた配列を格納するための新しい配列を作成
    int reordered_array[n];

    // 元の配列を昇順にソート
    sort(arr, arr + n);

    // 最小要素と最大要素のインデックスを指す変数を初期化
    int x = 0, y = n - 1;
    int i = 0;

    // x が y 以下である限り配列を走査
    while (x <= y) {
        // i が偶数の場合は最小側の要素を格納
        if (i % 2 == 0) {
            reordered_array[i] = arr[x];
            x++;
        }
        // i が奇数の場合は最大側の要素を格納
        else {
            reordered_array[i] = arr[y];
            y--;
        }
        i++;
    }
    // 並べ替えた配列を出力
    for (int i = 0; i < n; i++)
        cout << reordered_array[i] << " ";

    // もしくは、元の配列を更新してもよい
    // for (int i = 0; i < n; i++)
    // arr[i] = reordered_array[i];
    return 0;
}

出力

2 15 4 13 6 11 8

コードの解説

  • 変数は x = 0、y = 配列の長さ(n) - 1 として初期化されます。
  • while (x <= y) ループによって、x が y より大きくなるまで配列を走査します。
  • インデックス i が偶数の場合、最小側の要素(arr[x])を結果の配列に格納し、変数 x を1増やします。
  • インデックス i が奇数の場合、最大側の要素(arr[y])を結果の配列に格納し、変数 y を1減らします。
  • 最終的に、並べ替えられた配列が reordered_array[ ] に格納されます。

まとめ

本記事では、与えられた配列を「最小値 → 最大値 → 2番目に小さい値 → 2番目に大きい値…」という形で交互に並べ替えるアルゴリズムについて解説し、あわせてC++での実装例を紹介しました。ソート後に2つのポインタを両端から動かすだけというシンプルな手法で、実装も非常に容易です。同じロジックはC、Java、Pythonなど他の言語でも同様に実装できます。本記事が皆さんの学習の一助となれば幸いです。

  1. 【C++】二分探索木(BST)でk番目に小さい要素を検索する方法

    問題概要二分探索木(BST)と整数 k が入力として与えられたとき、木の中で k番目に小さい要素 を見つける問題を解説します。例えば、以下のようなBSTを考えてみましょう。この木に対して k = 3 を指定した場合、出力は 15 になります。木の要素を昇順に並べると「9, 13, 15, 17, 19, 25, 27」となり、3番目の値が15であるためです。アルゴリズムの考え方二分探索木には、「中順走査(in-order traversal)」を行うと要素が昇順に訪問されるという重要な性質があります。この性質を利用し、走査中に訪問したノード数をカウントしていき、k番目に到達した時点でそのノード

  2. C++で配列の最大要素とその位置を見つける方法

    配列の最大要素とは配列には複数の要素が格納されており、その中で他のすべての要素よりも大きい値を持つものが「最大要素」です。具体例51724上記の配列の場合、最大要素は7であり、インデックス2の位置に存在します。それでは、配列の最大要素を求めるC++プログラムを見ていきましょう。サンプルコード#include <iostream> using namespace std; int main() { int a[] = {4, 9, 1, 3, 8}; int largest, i, pos; largest = a[0]; for(i=1; i<