shakerSort関数

本ページには広告が含まれています。

引数に指定された配列をシェーカーソートで並び替えます。

構文
shakerSort( array )
引数
array 必須
ソートする数値を格納した配列。参照引数。
戻り値

プログラム

UWSC
//////////////////////////////////////////////////
// 【引数】
//   array : ソートする数値を格納した配列。参照引数。 
// 【戻り値】
//   
//////////////////////////////////////////////////
PROCEDURE shakerSort(Var array[])
	DIM topIndex = 0
	DIM bottomIndex = UBound(array) - 1
	WHILE TRUE
		DIM lastSwapIndex = topIndex
		FOR n = topIndex TO bottomIndex
			IFB array[n] > array[n+1] THEN
				swap(array[n], array[n+1])
				lastSwapIndex = n
			ENDIF
		NEXT
		bottomIndex = lastSwapIndex
		IF topIndex = bottomIndex THEN BREAK
		FOR n = bottomIndex TO topIndex + 1 STEP -1
			IFB array[n] < array[n-1] THEN
				swap(array[n], array[n-1])
				lastSwapIndex = n
			ENDIF
		NEXT
		topIndex = lastSwapIndex
		IF topIndex = bottomIndex THEN BREAK
	WEND
FEND

//////////////////////////////////////////////////
// 【引数】
//   inputs : 繰り返す文字列 
//   multiplier : inputsを繰り返す回数 
// 【戻り値】
//   inputsをmultiplier回を繰り返した文字列を返します 
//////////////////////////////////////////////////
FUNCTION strRepeat(inputs, multiplier)
	DIM res = ""
	FOR n = 1 TO multiplier
		res = res + inputs
	NEXT
	RESULT = res
FEND

//////////////////////////////////////////////////
// 【引数】
//   a : bと交換する値。参照引数。 
//   b : aと交換する値。参照引数。 
// 【戻り値】
//   
//////////////////////////////////////////////////
PROCEDURE swap(Var a, Var b)
	DIM tmp = a
	a = b
	b = tmp
FEND

//////////////////////////////////////////////////
// 【引数】
//   arrayname : 上限値を求める配列の名前 
//   dimension : 返す次元を示す整数 
// 【戻り値】
//   配列の上限値 
//////////////////////////////////////////////////
FUNCTION UBound(arrayname[], dimension = 1)
	RESULT = EVAL("RESIZE(arrayname" + strRepeat("[0]", dimension - 1) + ")")
FEND

解説

  1. 2-3行目
    UWSC
    	DIM topIndex = 0
    	DIM bottomIndex = UBound(array) - 1
  2. 4,22行目
    UWSC
    	WHILE TRUE
    		…
    	WEND
    無限ループ。
  3. 5行目
    UWSC
    		DIM lastSwapIndex = topIndex
    lastSwapIndexにtopIndexを代入。
  4. 6,11行目
    UWSC
    		FOR n = topIndex TO bottomIndex
    			…
    		NEXT
    topIndexがbottomIndexになるまで繰り返す。
  5. 7-10行目
    UWSC
    			IFB array[n] > array[n+1] THEN
    				swap(array[n], array[n+1])
    				lastSwapIndex = n
    			ENDIF
    配列のn番目がn+1番目より大きかったら、その2つを入れ替える。lastIndexにnを代入する。
  6. 12行目
    UWSC
    		bottomIndex = lastSwapIndex
    bottomIndexにlastSwapIndexを代入。
  7. 13行目
    UWSC
    		IF topIndex = bottomIndex THEN BREAK
    topIndexとbottomIndexが等しかったらループを抜ける。
  8. 14,19行目
    UWSC
    		FOR n = bottomIndex TO topIndex + 1 STEP -1
    			…
    		NEXT
    bottomIndexからtopIndex+1まで繰り返す。
  9. 15-18行目
    UWSC
    			IFB array[n] < array[n-1] THEN
    				swap(array[n], array[n-1])
    				lastSwapIndex = n
    			ENDIF
    配列のn番目がn-1番目より小さかったら、その2つを入れ替える。lastIndexにnを代入する。
  10. 20行目
    UWSC
    		topIndex = lastSwapIndex
    bottomIndexにlastSwapIndexを代入。
  11. 21行目
    UWSC
    		IF topIndex = bottomIndex THEN BREAK
    topIndexとbottomIndexが等しかったらループを抜ける。

使い方

UWSC
DIM array[] = 8, 20, 2, 22, 17, 30, 14, 4, 25, 5

shakerSort(array)

FOR item IN array
	PRINT item
NEXT
結果
プレーンテキスト
2
4
5
8
14
17
20
22
25
30

シェーカーソート

シェーカーソートは、ソートのアルゴリズムの一つです。バブルソートを改良したもの。双方向バブルソート、改良交換法とも言われます。

バブルソートでは、配列の要素を1つずつ比較していくため、逆に整列された配列の場合には非常に遅いという問題があります。シェーカーソートは、配列を前から順番に比較するだけでなく、後ろからも比較することで、配列の整列をより効率的に行います。

アルゴリズム

バブルソートで1回スキャンを行うと最後の要素1個がスキャン範囲中最大であることがわかり、次回のスキャン範囲を1狭めることができます。さらに、このスキャンの最後で連続してm個の要素の交換が行われていなければそのm個についてはソート済みであることが分かるので、次回のスキャン範囲をm狭めることができます。この工夫で、後半が殆ど整列済みのデータに対してバブルソートが高速に行えるようになります。

最悪計算時間 \(O(n^{2})\)
  1. 最初に、カレントポインタを配列の先頭、終端ポインタを配列の末尾に設定します。
  2. カレントポインタが終端ポインタに到達するまで、以下の処理を繰り返します。
    1. カレントポインタとその次の要素を比較し、大小関係が逆ならば、交換します。
    2. カレントポインタを1つ進めます。
    3. 終端ポインタとその前の要素を比較し、大小関係が逆ならば、交換します。
    4. 終端ポインタを1つ戻します。
  3. カレントポインタが終端ポインタに到達したら、ソートが完了です。

関連記事

QSORT関数 (スクリプト関数)
QSORT関数は、配列の中身をソートする関数です。戻値はありません。昇順・降順・UNICODE文字比較 昇順・UNICODE文字比較 降順・自然順ソート 昇順・自然順ソート 降順のいずれかを指定することができます。
small関数 (自作関数)
配列の中で小さい方から数えた順位の値を求めます。
bubbleSort関数 (自作関数)
引数に指定された配列を バブルソート で並び替えます。
gnomeSort関数 (自作関数)
引数に指定された配列を ノームソート で並び替えます。
insertionSort関数 (自作関数)
引数に指定された配列を 挿入ソート で並び替えます。
shellSort関数 (自作関数)
引数に指定された配列を シェルソート で並び替えます。
heapSort関数 (自作関数)
引数に指定された配列を ヒープソート で並び替えます。
quickSort関数 (自作関数)
引数に指定された配列を クイックソート で並び替えます。
shearSort関数 (自作関数)
引数に指定された配列を シェアソート で並び替えます。
Sort.Header プロパティ (Excel)
最初の行にヘッダー情報が含まれるかどうかを指定します。