AIZU ONLINE JUDGE

AOJ ALDS1 2_B(Selection Sort)を解く

AOJ_ALDS1_2_B

Aizu Online Judge(AOJ)が提供している「アルゴリズムとデータ構造入門」(ALDS1)の2_B問題をC++で解いてみました。

ALDS1では、「アルゴリズムとデータ構造の基礎を体得します。」とあります。トピック#2「初等的ソート」では、考え方が分かりやすいソートアルゴリズムを学びます。

問題(2_B: Selection Sort)

問題はリンク先をご覧ください。

AOJ ALDS1 2_B問題: Selection Sort

選択ソートについて学びます。

選択ソートについて

「残りの範囲から一番小さい値を選択する」ことを繰り返してソートします。最初は全範囲を対象として、1要素ずつ範囲を小さくしていきます。問題に紹介されている以下の擬似コードで実現できます。

selectionSort(A, N) // N個の要素を含む0-オリジンの配列A
    for i が 0 から N-1 まで
        minj = i
        for j が i から N-1 まで
            if A[j] < A[minj]
            minj = j
        A[i] と A[minj] を交換

選択ソートの特徴は以下です。

  • 計算量は、$O(N^2)$
  • 離れた場所の要素を入れ替えるため安定なソートではない(unstable sort)
  • 段階的に一番小さい要素を選ぶという考え方は分かりやすい。

C++ プログラム例(ALDS1 2_B)

問題で与えられる数列を選択ソートを用いてソートします。ソート後の文字列と交換した回数(関数 swap の呼び出し回数)を出力します。

プログラムのベースは、ALDS1 1_A(挿入ソート)を流用してます。

C++ でコーディングしたため、配列ではなく vector コンテナを使いました。このため、擬似コードにあった $N$ は引数として渡していません。これは vector コンテナでは要素数を size() メソッドで取得できるからです。

以下の3関数から成ります。

  • 関数 print_vector : 引数で与えらえた vector コンテナの要素を空白区切りで出力します。
    • 要素の後の空白と改行を、文字列 ” \n” (空白と改行コードの2文字)と添え字の演算子 (i == a.size() – 1) の値が 0 か 1 となることを用いて出力しています。多少読みにくいですが、1行で書けるため、この書き方を使っています。
  • 関数 selectionSort : 擬似コードをそのままコードにしました。swap した回数を返しています。
  • 関数 main : 要素数 $N$ と数列 $A$ を読み込み、selectionSort を呼び出します。

以下が、C++プログラムとなります。

#include <iostream>
#include <vector>
#include <algorithm> // swap C++03
#include <utility>   // swap C++11 or later
using namespace std;

void print_vector(vector<int> a)
{
	for (int i = 0; i < a.size(); ++i) {
		cout << a[i] << " \n"[i == a.size() - 1];
	}
}

int selectionSort(vector<int>& a)
{
	int n_swap = 0;

	for (int i = 0; i < a.size(); ++i) {
		int minj = i;
		for (int j = i; j < a.size(); ++j) {
			if (a[j] < a[minj]) {
				minj = j;
			}
		}
		if (i != minj) {
			swap(a[i], a[minj]);
			++n_swap;
		}
	}

	return n_swap;
}

int main()
{
	int n;
	cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; ++i) {
		cin >> a[i];
	}

	int n_swap =  selectionSort(a);
	print_vector(a);
	cout << n_swap << endl;

	return 0;
}

上記プログラムは、AOJ で「AC(Accepted=正解)」と判定されました。

最後に

挿入ソートバブルソートに続き、選択ソートを学びました。選択ソートは前の2つのソートアルゴリズムと異なり安定ではありません。

選択ソートは速いとは言えませんが、分かりやすい考え方のアルゴリズムです。

引き続き、ALDS1 の問題を紹介していきます。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA