コミック:カクテルソーティングとは何ですか?
上の「プログラマーXiaohui」をクリックし、公式アカウントをフォローして、
興味深く有意義な記事をできるだけ早く配信することを選択してください。
前回のコミックで、Xiao Huiはバブリングソーティングのアイデアといくつかの変更を紹介しました:
コミック:バブルソートとは何ですか?
それで、神聖な種類のカクテルは何ですか?この号で詳しくお話します。
最初に
バブルソートの概念を確認しましょう。バブルソートの各要素は小さなバブルのようになり、サイズに応じてアレイの片側に少しずつ移動します。アルゴリズムの各ラウンドで、要素が左から右に比較され、一方向の位置交換が実行されます。
では、カクテルソーティングのためにどのような最適化が行われたのでしょうか?
カクテルソーティングの要素比較と交換プロセスは双方向です。
栗を取りましょう:
順序付けられていないシーケンスを形成するための8つの番号があります:2、3、4、5、6、7、8、1、そして小さいものから大きいものへのソートを望んでいます。
バブリングソーティングのアイデアに従う場合、ソーティングプロセスは何ですか?
第1ラウンドの結果(8回と1回の交換)
第2ラウンドの結果(7回と1回の交換)
第3ラウンドの結果(6回と1回の交換)
第4ラウンドの結果(5回と1回の交換)
第5ラウンドの結果(4回と1回の交換)
第6ラウンドの結果(3回と1回の交換)
第7ラウンドの結果(2回と1回の交換)
カクテルの種類はどのように見えますか?詳細なプロセスを見てみましょう。
最初のラウンド(バブルソートと同じ、8と1の交換)
第2ラウンド
この時点では異なります。右から左に比較して交換します。
8はすでに注文エリアにあります。8を無視し、1と7を比較します。要素1は7未満であるため、1と7のスワップ位置:
1と6の次の比較では、要素1は6未満であるため、1と6は位置を交換します。
1と5の次の比較では、要素1は5未満であるため、1と5のスワップ位置は次のようになります。
次の1と4の交換、1と3の交換、および1と2の交換は、最終的に次の結果になりました。
第3ラウンド(順調ですが、プロセスは終了していません)
カクテルソーティングの第3ラウンドでは、左から右にもう一度比較して交換する必要があります。
1と2を比較すると、位置は変わりません。2と3を比較すると、位置は同じです。3と4を比較すると、位置は同じです... 6と7を比較すると、位置は同じです。
要素の位置交換はなく、証明はすでに整っており、並べ替えは終了します。
これは、カクテルを分類するというアイデアです。仕分けプロセスは振り子のようなものです。1回目は左から右へ、2回目は右から左へ、3回目は左から右へ...
public class CockTailSort {
private static void sort(int array[])
{
int tmp = 0;
for(int i=0; i<array.length/2-1; i++)
{
//有序标记,每一轮的初始是true
boolean isSorted = true;
//奇数轮,从左向右比较和交换
for(int j=i; j<array.length-i ; j++)
{
if(array[j] > array[j+1]
{
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
}
}
if(isSorted){
break;
//偶数轮,从右向左比较和交换
for(int j=array.length-i-1; j>i; j--)
{
if(array[j] < array[j-1])
tmp = array[j];
array[j] = array[j-1]
array[j-1] = tmp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
}
if(isSorted){
break;
}
}
}
public static void main(String[] args){
int[] array = new int[]{2,3,4,5,6,7,8,1};
sort(array);
System.out.println(Arrays.toString(array));
}
}
このコードは、カクテル選別の元の実装です。コードの外側にある大きなループは、すべての並べ替えラウンドを制御します。大きなループには2つの小さなループが含まれます。最初のループは要素を左から右に比較して交換し、2番目のループは要素を右から左に比較して交換します。
順序付けられた領域の偽の並べ替えの最適化のアイデアを確認しましょう。
元のバブルソートでは、順序付けられた領域の長さはソートのラウンド数と同じです。たとえば、1回目の並べ替え後の順序付き領域の長さは1で、2回目の並べ替え後の順序付き領域の長さは2です。
最適化するために、ソートの各ラウンドの最後に最後の要素交換の位置を記録できます。その位置は、順序付けされていないシーケンスの境界であり、次に順序付けられた領域です。
一方向バブルソーティングの場合は境界値を設定する必要があり、双方向カクテルソーティングの場合は2つの境界値を設定する必要があります。コードを参照してください:
public class CockTailSort {
private static void sort(int array[])
{
int tmp = 0;
//记录右侧最后一次交换的位置
int lastRightExchangeIndex = 0;
//记录左侧最后一次交换的位置
int lastLeftExchangeIndex = 0
//无序数列的右边界,每次比较只需要比到这里为止
int righttBorder = array.length - 1;
//无序数列的左边界,每次比较只需要比到这里为止
int leftSortBorder = 0;
for(int i=0; i<array.length/2 ; i++)
//有序标记,每一轮的初始是true
boolean isSorted = true;
//数轮,从左向右比较和交换
for(int j=leftSortBorder; j<rightSortBorder; j++)
{
if(array[j] > array[j+1])
{
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
lastRightExchangeIndex = j;
}
}
rightSortBorder = lastRightExchangeIndex;
if(isSorted){
break
}
//偶数轮,从右向左比较和交换
for(int j=rightSortBorder; j>leftSortBorder; j--)
{
if(array[j] < array[j-1])
{
tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
lastLeftExchangeIndex = j;
}
}
コードは左と右の境界値を使用し、rightSortBorderは右の境界を表し、leftSortBorderは左の境界を表します。
要素を比較および交換する場合、奇数のラウンドはleftSortBorderからrightSortBorderの位置に移動し、偶数のラウンドはrightSortBorderからleftSortBorderの位置に移動します。
- - -終わり - - -
この記事が気に入った友達は、写真を長押ししてサブスクリプションアカウントプログラマーのXiaohuiをフォローし、よりエキサイティングなコンテンツをご覧ください。