【アルゴリズム】バブルソート+選択ソート+挿入ソート

目次

序文

1.バブルソート

2.並べ替えを選択します

3.挿入ソート


序文

この記事では、バブルソート、選択ソート、挿入ソートのアルゴリズム(思考の説明+アニメーション+コード(Java言語))について説明します。これらは3つの単純なソートです。

 

1.バブルソート

1.1バブルソートのアイデア

隣接する2つの数字を順番に比較し、小さい数字を前に、大きい数字を後ろに置きます。

1.2バブルソート図

 

1.3バブルソートコードの実装

//冒泡排序,可直接运行
public class BubbleSort {

    public static void main(String[] args) {
        int[] arr = {9,6,14,2,55,12,34,7};
        sortByBubble(arr);
        for (int i = 0;i < arr.length;i++){
            System.out.print(arr[i]+" ");
        }
    }

    private static void sortByBubble(int[] arr) {
        if (arr==null || arr.length < 2){
            return;
        }
        boolean flag;
        for (int i = 0;i < arr.length;i++){
            flag = false;
            //此处-1是为了防止数组下标溢出 a[j+1]
            //若不减一,此处的例子上a[j+1]则会变成a[a.length]
            for (int j = 0;j < arr.length - i - 1;j++){
                int temp;
                if (arr[j] > arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    flag = true;
                }
            }
            if (!flag){
                break;
            }
        }
    }

}

初回通過ソート:

  •       最初のソート:9と6,9が6より大きい場合、交換位置[ 9,6、14,2,55,12,34,7]
  •       ソーティングの第二ラウンド:9及び14を、図9は、14未満、位置を交換しない[6、であり9,14 2,55,12,34,7]
  •       第三のソート時間:14及び第2の比較器14は2よりも大きい、変化位置[6,9 、2,14、55,12,34,7]
  •       選別の第4ラウンド:14と55を比較する、14は55未満であり、かつないスワップ位置[6,9,2、14,55、12,34,7]
  •         ソートの第5ラウンド:55と12を比較し、55は12より大きい、位置を交換します[ 6,9,2,14、12,55、34,7 ]
  •       第六の時系列:55と34を比較する、55は34よりも大きい、交換位置[6,9,2,14,12、34,55、7]
  •                       第7ラウンドの順序:55と7を比較し、55が7より大きい場合、位置を交換します[ 6、9、2、14、12、34、7、55 ]
  •       最初のパスで合計7つの比較が行われ、並べ替えられた結果:[6,9,2,14,12,34,7,55]

 

2回目の並べ替え:

  •       最初の並べ替え:6と9、6は9未満で、位置を入れ替えることはありません[ 6,9、2,14,12,34,7,55]
  •       2回目の並べ替え:9と2、9は2より大きい、位置を交換する[ 6、2、9、14、12、34、7、55]
  •       第三のソート時間:14未満9と比較して9と14、[6,2、位置を変更しない9,14、12,34,7,55]
  •       選別の第4ラウンド:12と14、14は12よりも大きい、交換位置[6,2,9、12,14、34,7,55]
  •         第五のソート時間:14およびコンパレータ34、14が位置を交換することなく、34未満である[6,2,9,12、14、34、7.55]
  •       第六の時系列:34および7を比較し、34 7よりも大きい、交換位置[6,2,9,12,14、7,34、55]
  •       2回目のパスで合計6つの比較が行われ、並べ替えられた結果は次のとおりです。[6,2,9,12,14,7,34,55]

3番目の時系列:

  •       最初のソート:6および比較2、6は2より大きい、位置を変更する[ 2,6、9,12,14,7,34,55]
  •       ソーティングの第二ラウンド:比較6,9、6未満9、位置を交換しない[2、である6,9、12,14,7,34,55]
  •       ソーティングの第三ラウンド:9と12の比較を、図9は、12未満では、[2,6、位置を交換していない9,12、14,7,34,55]
  •       選別の第4ラウンド:[位置12と14、12が14未満である交換しない2,6,9- 12,14、7,34,55]
  •         第五のソート時間:14と比較7、7より大きく14、交換位置[2,6,9,12、7、14、34,55]
  •       3番目のパスで合計5つの比較が行われ、並べ替えられた結果:[2,6,9,12,7,14,34,55]

4番目のパスの並べ替え:

  •       最初の分類:2,6、2は6未満である、位置を入れ替える[いない2,6、9,12,7,14,34,55]
  •       2番目のパスの並べ替え:6および比較9、6は9未満、交換位置なし[ 2、6、9、12、7、14、34、55]
  •       第三のソート時間:12未満9と比較して9と12、[2,6、位置を変更しない9,12、7,14,34,55]
  •       第四のソート時間:12と比較7、7より大きく12、交換位置[2,6,9-、7,12、14,34,55]
  •       4回目のパスで合計4つの比較が行われ、結果が並べ替えられました:[2,6,9,7,12,14,34,55]

5番目の時系列:

  •       第1選別:2,6、2は6未満、位置を交換しないである[ 2,6、9,7,12,14,34,55]
  •       ソートの第2ラウンド:6と9、6は9未満であり、位置を交換しないでください[ 2、6、9、7、12、14、34、55]
  •       3番目の時系列:9と7、9は12より大きく、位置を交換します[ 2、6、7、9、12、14、34、55]
  •       5回目のパスで合計3つの比較が行われ、並べ替えられた結果:[2,6,7,9,12,14,34,55]

6番目の時系列:

  •       最初の分類:2,6、2は6未満である、位置を入れ替える[いない2,6、7,9,12,14,34,55]
  •       ソーティングの第二ラウンド:6と7を比較し、6、7未満でないスワップ位置[2、6,7、9,12,14,34,55]
  •       第6ラウンドでは、合計2つの比較が行われ、結果が並べ替えられました:[2,6,7,9,12,14,34,55]

7番目のパスの並べ替え:

  •       最初の分類:2,6、2は6未満である、位置を入れ替える[いない2,6、7,9,12,14,34,55]
  •       7番目のパスでは、合計1つの比較が行われ、並べ替えられた結果:[2,6,7,9,12,14,34,55]

 

 

1.4バブルソートの時間計算量分析

フラグ変数を設定した後:

元のシーケンスが「正の順序」で配置されている場合、バブルソートの比較の総数はn-1であり、移動の数は0です。これは、最良の場合のバブルソートの時間計算量がO(n );

元のシーケンスを「逆順」でソートした場合、バブルソートの比較の総数はn(n-1)/ 2、移動回数は3n(n-1)/ 2回なので、最悪の場合-バブルソートのケース時間複雑さはO(n ^ 2)です。

元のシーケンスが故障している場合、バブルソートの平均時間計算量はO(n ^ 2)です。

 

1.5バブルソートのスペースの複雑さ

バブルソートプロセスでは、ペアワイズ交換のために一時変数が必要であり、必要な追加スペースは1であるため、スペースの複雑さはO(1)です。

2.並べ替えを選択します

2.1並べ替えのアイデアを選択する

1.各トラバーサルプロセスでは、最初のインデックスの要素が最小値であると想定され、他のインデックスの値と順番に比較されます。

現在のインデックスの値が他のインデックスの値よりも大きい場合、他のインデックスの値が最小値であると見なされ、最後に最小値が配置されているインデックスを見つけることができます。

2.最初のインデックスの値と最小のインデックスを交換します。

2.2選択とソートの図

2.3ソートコード実装の選択

/**
 * 选择排序,可直接运行
 */
public class SelectionSort {

    public static void main(String[] args) {
        int[] arr = {9,6,14,2,55,12,34,7};
        sortBySelect(arr);
        for (int i = 0;i < arr.length;i++){
            System.out.print(arr[i]+" ");
        }
    }

    private static void sortBySelect(int[] arr) {
        if (arr ==null || arr.length < 2){
            return;
        }
        for (int i = 0; i < arr.length -1; i++) {
            //假定本次遍历,最小值所在的索引是i
            int min = i;
            int temp;
            //需要理解这里的 i+1 和 j < arr.length
            for (int j = i+1; j < arr.length; j++) {
                if (arr[min] > arr[j]){
                    //找到一个比自己小的就把它记下来,
                    //接着再用这个比自己小的和后续的比较
                    min = j;
                }
            }
            //此时arr[min]为最小的,和刚开始假定的最小值arr[i]进行交换
            temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }
    }
}

 

2.4選択ソートの時間計算量分析

選択的並べ替えでは、外側のループがデータ交換を完了し、内側のループがデータ比較を完了する二重層のforループを使用するため、データ交換とデータ比較の数を個別にカウントします。

データ比較時間:(N-1)+(N-2)+(N-3)+ ... + 2 + 1 =((N-1)+1)*(N-1)/ 2 = N ^ 2 / 2-N / 2;

データ交換の数:N-1

時間計算量:N ^ 2 / 2-N / 2 +(N-1)= N ^ 2/2 + N / 2-1;

大きなO微分法則によれば、最高次の項が保持され、定数係数が削除され、時間計算量はO(N ^ 2)です。

2.5選択ソートの空間複雑性分析

スペースの複雑さ。最適な場合(すでに順序付けられている)の複雑さは次のとおりです。O(0);最悪の場合(すべての要素を並べ替える必要があります)の複雑さは次のとおりです。O(n);;平均時間計算量次数:O( 1)

 

3.挿入ソート

3.1挿入ソートの原則

1.ソートされる最初のシーケンスの最初の要素を順序付けられたシーケンスとして扱い、最後の要素までの2番目の要素をソートされていないシーケンスとして扱います。

2.ソートされていないシーケンスを最初から最後までスキャンし、スキャンした各要素を順序付けられたシーケンスの適切な位置に挿入します。

(挿入される要素が順序付けられた順序の要素と等しい場合、挿入される要素は等しい要素の後に挿入されます。)

3.2挿入ソート図

3.3挿入ソートコードの実装

/**
 * 插入排序,可直接运行
 */
public class InsertSort {
    public static void main(String[] args) {
        int[] arr = {9, 6, 14, 2, 55, 12, 34, 7};
        sortByInsert(arr);
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }

    private static void sortByInsert(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        //从数组下标为 1 的地方和前面的元素进行比较,开始选择合适的地方进行插入
        //因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < arr.length; i++) {
            //把该需要比较的元素先保存一份
            int temp = arr[i];
            //从已经排序的最右边开始进行比较,找到比其小的数
            int j = i;
            while(j>0 && temp < arr[j - 1]){
                //如果比较的元素小的话,将比较的对应元素向后移动
                arr[j] = arr[j - 1];
                j--;
            }
            //如果j==i,那么排好序的元素都比需要比较的元素小,不需要插入
            //如果j!=i,那么说明有比需要比较的元素小的数,并且位置移动了,需要插入
            if (j!=i){
                arr[j] = temp;
            }
        }
    }

}

 

 

3.4挿入ソートの時間計算量分析:

挿入ソートでは、二重層のforループを使用します。この場合、内部ループのループ本体は実際にソートを完了するコードです。したがって、挿入ソートの時間計算量を分析し、主に内部ループ本体の実行回数を分析します。

最悪の場合、ソートされる配列要素は{55,34,14,12,9,7,6,2}であり、次のようになります。

比較の数は次のとおりです:(N-1)+(N-2)+(N-3)+ ... + 2 + 1 =((N-1)+ 1)*(N-1)/ 2 = N ^ 2 / 2-N / 2;

交換の数は次のとおりです:(N-1)+(N-2)+(N-3)+ ... + 2 + 1 =((N-1)+ 1)*(N-1)/ 2 = N ^ 2 / 2-N / 2;

実行の総数は次のとおりです。(N ^ 2 / 2-N / 2)+(N ^ 2 / 2-N / 2)= N ^ 2-N;

 

Big Oの導出規則によれば、関数の最上位の項が保持されている場合、最終的な挿入ソートの時間計算量はO(N ^ 2)です

挿入ソートは、比較的大量のデータを含むアプリケーションのソートには適していません。ただし、ソートするデータの量が少ない場合、たとえば、マグニチュードが1,000未満の場合、または入力要素が大まかに並べられていることがわかっている場合は、挿入ソートを選択することをお勧めします。挿入ソートは、産業グレードのライブラリでも広く使用されています。STLのソートアルゴリズムとstdlibのqsortアルゴリズムでは、挿入ソートは、少数の要素をソートするためのクイックソートの補足として使用されます。

==================================================

また、この記事がお役に立てばと思いますら、下のようにクリックしてください!     
あなたのサポートが私の粘り強さです。

==================================================

おすすめ

転載: blog.csdn.net/i_nclude/article/details/112682852