配列内の数値を整列させる_3(挿入法)
配列内の数値を、昇順(降順)に整列してみます。
反復(繰り返し)処理のネスト(入れ子)処理の
基礎として配列内数値の整列がよく説明されています。
この基本的な整列法として、選択法、隣接交換法、挿入法が
あります。
挿入法の簡単な解説とプログラムしてみます。
※この説明では、昇順にすることが前提です。
1.最初は、配列要素全体が未整列要素です。
この先頭要素を整列確定要素とします。
2.確定要素の末尾の次の要素(未整列要素の先頭)を
確定要素の末尾から先頭に向かって順に比較します。
3.比較結果が、確定要素 > 未整列の先頭要素
の間は、その前の確定要素へと比較を進めます。
4.比較結果が、確定要素 < 未整列の先頭要素
となった位置の1つ後方の位置が、未整列先頭要素の
適切な挿入位置となります。
5.位置が確定し挿入する場合、その位置に空き
領域を用意する必要があります。
空き領域の確保には、挿入位置から整列済み
末尾までの要素の値を、1要素分後ろにずらします。
※この1要素分をずらす方法として、
・3.の比較時に比較しながら後ろにずらす。
・4.の挿入位置が確定した時点でまとめてずらす。
のどちらかになります。
6.確保できた空き領域に、未整列の先頭要素を
写します。
7.比較に使用した未整列の先頭要素の位置までを
整列確定要素とし、2.の操作から処理を繰り返します。
8.未整列要素が無くなった(配列要素の末尾まで
整列済みとなった)時点で整列操作は完了です。
この解説を図にしてみました。
※この図では、比較時に後方へずらす処理を行っています。
では、整列_挿入法をプログラムしてみます。
・プロジェクトを作成します。
Visual Studio 2022を起動し、
新しいプロジェクトを作成します。
・プロジェクトタイプ:"コンソールアプリ"
・プロジェクト名:"ct_107_3"
とします。
・プログラム記述・編集画面が表示されるので、
以下のプログラムを記述します。
プログラムの記述内容
// 配列内の数値を整列させる // 挿入法による昇順(降順) #include <iostream> int main() { // 変数宣言と初期化 int array[] = { 5,1,7,6,4,8,2,10,3,9 }; int num; int work; int index; // array配列の要素数を取得 num = sizeof(array) / sizeof(array[0]); // 整列前の配列内数値の表示 printf("整列前 :"); for (int i = 0; i < num; i++) { printf("%4d", array[i]); } printf("\n"); // その値の正規位置を探しながらの入替ループ for (int head = 1; head < num; head++) { work = array[head]; for (index = head - 1; index >= 0 && array[index] > work; index--) { array[index + 1] = array[index]; } array[index + 1] = work; } // 整列後の配列内数値の表示 printf("整列後 :"); for (int i = 0; i < num; i++) { printf("%4d", array[i]); } printf("\n"); return EXIT_SUCCESS; }
簡単なプログラム解説です。
このプログラムでは、比較し挿入位置とは違う場合、 後方へ値を移しながら比較を進めるプログラム例です。 ※挿入位置確定後に、まとめて整列要素を後方へ移す プログラム例ではありません。 ・変数宣言と初期化 int array[] = { 5,1,7,6,4,8,2,10,3,9 }; 整列に使用する未整列値の配列を宣言します。 int num; 配列の要素数を格納するための変数 int work; 未整列の先頭要素(未整列側の比較対象要素)の仮置き用変数 ※後方へずらす場合に、この要素位置を使用するためです。 int index; 確定済み配列要素の比較位置を格納するための変数 ・array配列の要素数を取得 num = sizeof(array) / sizeof(array[0]); この式によって、配列内の要素数を取得できます。 ・整列前の配列内数値の表示 printf("整列前 :"); for (int i = 0; i < num; i++) { printf("%4d", array[i]); } printf("\n"); 整列前の要素の値を表示するためのループ処理 ・その値の正規位置を探しながらの入替ループ for (int head = 1; head < num; head++) { 未整列配列の比較対象位置を1つずつ後方へずらしながらのループ work = array[head]; 未整列の先頭要素(整列させる)値を仮置きします。 for (index = head - 1; index >= 0 && array[index] > work; index--) { 整列済み配列を末尾から先頭に向かって比較するループ array[index + 1] = array[index]; 比較した結果、確定要素の比較対象 > 未整列要素の比較対象の場合、 その確定要素側の比較対象要素の値を1つ後方へずらします。 ※最初の比較での後方位置は、未整列配列の先頭位置となります。 } array[index + 1] = work; 比較した結果、確定要素の比較対象 < 未整列要素の比較対象の場合、 その未整列要素側の比較対象要素の値を1つ後方位置に複写します。 ※この複写位置は、元の値は後方に移されているので、空き領域となっています。 } ・整列後の配列内数値の表示 printf("整列後 :"); for (int i = 0; i < num; i++) { printf("%4d", array[i]); } printf("\n"); 整列後の要素の値を表示するためのループ処理
・実行してみます。
上段メニュー"デバッグ(D)"のサブメニューより、
"デバッグなしで開始(H)"を選択します。
・実行結果は、デバッグコンソール画面が開き表示されます。
※この実行では、整列前の配列内の値と、
整列後の配列内の値を表示しています。
※この画面は、何かのキーを打鍵することで閉じることができます。