ソート-交換ソート-バブルソート

バブルソート

バブル ソートは、最も単純な交換ソート方法です。隣接するレコードのキーワードをペアごとに比較します。順序が逆になると交換され、小さなキーワードを含むレコードがバブルのように徐々に上に「浮いて」いきます ( (左シフト)、または大きなキーワードを含むレコードを石のように徐々に「落下」させます (右にシフト)。

アルゴリズムのアイデア

【アルゴリズムステップ】

① ソート対象のレコードが配列 r[1...n] に格納されているとします。まず、1 番目のレコードのキーの合計と 2 番目のレコードのキーワードを比較し、順序が逆 (つまり、L.elem[1].key > L.elem[2].key) の場合は、キーの合計を交換します。 2枚のレコードです。次に、2 番目のレコードと 3 番目のレコードのキーワードを比較します。以降、n-1 番目のレコードと n 番目のレコードのキーワードが比較されるまで続きます。
以上の処理がバブルソートの1パス目となり、キーワードが最も大きいレコードが最終レコードの位置に配置されることになります。
② 次に 2 回目のバブルソートを実行し、最初の n-1 レコードに対して同じ操作を実行すると、2 番目に大きいキーワードを持つレコードが n-1 番目の分野の位置に配置されます。
③ 上記の比較・交換処理を繰り返す i 回目では、L.elem[1] から l.elem[n-i+1] までの隣接する 2 つのレコードのキーワードを比較し、隣接するレコードを「逆順」に交換します。 「order」レコードの場合、n-i+1 個のレコードの中で最も大きなキーワードを持つレコードが n-i+1 番目の位置に置き換えられます。
特定の並べ替えプロセス中にレコード交換操作がなくなるまで、すべてのシーケンスが並べ替え要件を満たしていることを意味します。

アルゴリズムの実装

レコードを保存するための線形テーブル構造を定義する

 //记录
 typedef struct ElemType{
    
    
     int key;
     string info;
 }ElemType;

#define Maxsize 50
 typedef struct {
    
    
     ElemType elem[Maxsize];
     int length;
 }SqList;
 
/**
 * 对顺序表L进行降序 冒泡排序
 */
void BubbleSort(SqList &L);
/**
 * 对顺序表L进行升序 冒泡排序
 */
void Bubble_Sort(SqList &L);

void toString(SqList L);

void InitSqList(SqList &L);

void swap(ElemType &a, ElemType &b);

昇順コアの実装

void Bubble_Sort(SqList &L) {
    
    
    int n = L.length;
    for (int i = 0; i < n-1; i++) {
    
    
        cout << " -------------------------进行 i = " << i << " 趟排序------------------------------------------------- " << endl;
        bool flag = false;  //表示本趟冒泡是否发生的标志
        for (int j = n - 1; j > i; j--) {
    
     //一趟冒泡过程
            cout << " j = " << j;
            if (L.elem[j - 1].key > L.elem[j].key) {
    
     //若为逆序
                swap(L.elem[j - 1], L.elem[j]); //交换
                flag = true;
                cout << " 交换: " << j-1 << "," << j;
            }
            cout << endl;
            toString(L);
            if (!flag) {
    
    
                return; //若本趟遍历后没有发生交换,说明已经达到排序要求。
            }
        }
    }
}

降順のコア実装

void BubbleSort(SqList &L) {
    
    
    int m = L.length - 1;
    bool flag = true; //flag 用来记录某一趟排序是否发生交换
    while ((m > 0) && flag) {
    
    
        cout << " -------------------------剩余 m = " << m << "躺排序------------------------------------------------- " << endl;
        flag = false; //置为false 如果本趟没有发生交换,则不会指向下一趟排序
        for (int j = 0; j < m; j++) {
    
    
            cout << " j = " << j;
            if (L.elem[j].key < L.elem[j + 1].key) {
    
    
                flag = true; //本趟发生了交换
                swap(L.elem[j], L.elem[j + 1]);  //交换
                cout << " 交换: " << j << "," << j + 1;
            }
            cout << endl;
            toString(L);
        }
        m--;
    }
}

テストケース

void testBubbleSort() {
    
    
    SqList L;
    InitSqList(L);
    cout <<" ----------------------------------初始 L---------------------------------------- "<< endl;
    toString(L);
    BubbleSort(L);
    cout <<" ----------------------------------降序冒泡L---------------------------------------- "<< endl;
    toString(L);
    Bubble_Sort(L);
    cout <<" ----------------------------------升序冒泡L---------------------------------------- "<< endl;
    toString(L);
}

int main() {
    
    
    testBubbleSort();
    return 0;
}

試験結果

 ----------------------------------初始 L---------------------------------------- 
L.key  [ 41 67 34 0 69 24 78 58 62 64 ]
 -------------------------剩余 m = 9躺排序------------------------------------------------- 
 j = 0 交换: 0,1
L.key  [ 67 41 34 0 69 24 78 58 62 64 ]
 j = 1
L.key  [ 67 41 34 0 69 24 78 58 62 64 ]
 j = 2
L.key  [ 67 41 34 0 69 24 78 58 62 64 ]
 j = 3 交换: 3,4
L.key  [ 67 41 34 69 0 24 78 58 62 64 ]
 j = 4 交换: 4,5
L.key  [ 67 41 34 69 24 0 78 58 62 64 ]
 j = 5 交换: 5,6
L.key  [ 67 41 34 69 24 78 0 58 62 64 ]
 j = 6 交换: 6,7
L.key  [ 67 41 34 69 24 78 58 0 62 64 ]
 j = 7 交换: 7,8
L.key  [ 67 41 34 69 24 78 58 62 0 64 ]
 j = 8 交换: 8,9
L.key  [ 67 41 34 69 24 78 58 62 64 0 ]
 -------------------------剩余 m = 8躺排序------------------------------------------------- 
 j = 0
L.key  [ 67 41 34 69 24 78 58 62 64 0 ]
 j = 1
L.key  [ 67 41 34 69 24 78 58 62 64 0 ]
 j = 2 交换: 2,3
L.key  [ 67 41 69 34 24 78 58 62 64 0 ]
 j = 3
L.key  [ 67 41 69 34 24 78 58 62 64 0 ]
 j = 4 交换: 4,5
L.key  [ 67 41 69 34 78 24 58 62 64 0 ]
 j = 5 交换: 5,6
L.key  [ 67 41 69 34 78 58 24 62 64 0 ]
 j = 6 交换: 6,7
L.key  [ 67 41 69 34 78 58 62 24 64 0 ]
 j = 7 交换: 7,8
L.key  [ 67 41 69 34 78 58 62 64 24 0 ]
 -------------------------剩余 m = 7躺排序------------------------------------------------- 
 j = 0
L.key  [ 67 41 69 34 78 58 62 64 24 0 ]
 j = 1 交换: 1,2
L.key  [ 67 69 41 34 78 58 62 64 24 0 ]
 j = 2
L.key  [ 67 69 41 34 78 58 62 64 24 0 ]
 j = 3 交换: 3,4
L.key  [ 67 69 41 78 34 58 62 64 24 0 ]
 j = 4 交换: 4,5
L.key  [ 67 69 41 78 58 34 62 64 24 0 ]
 j = 5 交换: 5,6
L.key  [ 67 69 41 78 58 62 34 64 24 0 ]
 j = 6 交换: 6,7
L.key  [ 67 69 41 78 58 62 64 34 24 0 ]
 -------------------------剩余 m = 6躺排序------------------------------------------------- 
 j = 0 交换: 0,1
L.key  [ 69 67 41 78 58 62 64 34 24 0 ]
 j = 1
L.key  [ 69 67 41 78 58 62 64 34 24 0 ]
 j = 2 交换: 2,3
L.key  [ 69 67 78 41 58 62 64 34 24 0 ]
 j = 3 交换: 3,4
L.key  [ 69 67 78 58 41 62 64 34 24 0 ]
 j = 4 交换: 4,5
L.key  [ 69 67 78 58 62 41 64 34 24 0 ]
 j = 5 交换: 5,6
L.key  [ 69 67 78 58 62 64 41 34 24 0 ]
 -------------------------剩余 m = 5躺排序------------------------------------------------- 
 j = 0
L.key  [ 69 67 78 58 62 64 41 34 24 0 ]
 j = 1 交换: 1,2
L.key  [ 69 78 67 58 62 64 41 34 24 0 ]
 j = 2
L.key  [ 69 78 67 58 62 64 41 34 24 0 ]
 j = 3 交换: 3,4
L.key  [ 69 78 67 62 58 64 41 34 24 0 ]
 j = 4 交换: 4,5
L.key  [ 69 78 67 62 64 58 41 34 24 0 ]
 -------------------------剩余 m = 4躺排序------------------------------------------------- 
 j = 0 交换: 0,1
L.key  [ 78 69 67 62 64 58 41 34 24 0 ]
 j = 1
L.key  [ 78 69 67 62 64 58 41 34 24 0 ]
 j = 2
L.key  [ 78 69 67 62 64 58 41 34 24 0 ]
 j = 3 交换: 3,4
L.key  [ 78 69 67 64 62 58 41 34 24 0 ]
 -------------------------剩余 m = 3躺排序------------------------------------------------- 
 j = 0
L.key  [ 78 69 67 64 62 58 41 34 24 0 ]
 j = 1
L.key  [ 78 69 67 64 62 58 41 34 24 0 ]
 j = 2
L.key  [ 78 69 67 64 62 58 41 34 24 0 ]
 ----------------------------------降序冒泡L---------------------------------------- 
L.key  [ 78 69 67 64 62 58 41 34 24 0 ]
 -------------------------进行 i = 0 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 78 69 67 64 62 58 41 34 0 24 ]
 j = 8 交换: 7,8
L.key  [ 78 69 67 64 62 58 41 0 34 24 ]
 j = 7 交换: 6,7
L.key  [ 78 69 67 64 62 58 0 41 34 24 ]
 j = 6 交换: 5,6
L.key  [ 78 69 67 64 62 0 58 41 34 24 ]
 j = 5 交换: 4,5
L.key  [ 78 69 67 64 0 62 58 41 34 24 ]
 j = 4 交换: 3,4
L.key  [ 78 69 67 0 64 62 58 41 34 24 ]
 j = 3 交换: 2,3
L.key  [ 78 69 0 67 64 62 58 41 34 24 ]
 j = 2 交换: 1,2
L.key  [ 78 0 69 67 64 62 58 41 34 24 ]
 j = 1 交换: 0,1
L.key  [ 0 78 69 67 64 62 58 41 34 24 ]
 -------------------------进行 i = 1 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 78 69 67 64 62 58 41 24 34 ]
 j = 8 交换: 7,8
L.key  [ 0 78 69 67 64 62 58 24 41 34 ]
 j = 7 交换: 6,7
L.key  [ 0 78 69 67 64 62 24 58 41 34 ]
 j = 6 交换: 5,6
L.key  [ 0 78 69 67 64 24 62 58 41 34 ]
 j = 5 交换: 4,5
L.key  [ 0 78 69 67 24 64 62 58 41 34 ]
 j = 4 交换: 3,4
L.key  [ 0 78 69 24 67 64 62 58 41 34 ]
 j = 3 交换: 2,3
L.key  [ 0 78 24 69 67 64 62 58 41 34 ]
 j = 2 交换: 1,2
L.key  [ 0 24 78 69 67 64 62 58 41 34 ]
 -------------------------进行 i = 2 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 24 78 69 67 64 62 58 34 41 ]
 j = 8 交换: 7,8
L.key  [ 0 24 78 69 67 64 62 34 58 41 ]
 j = 7 交换: 6,7
L.key  [ 0 24 78 69 67 64 34 62 58 41 ]
 j = 6 交换: 5,6
L.key  [ 0 24 78 69 67 34 64 62 58 41 ]
 j = 5 交换: 4,5
L.key  [ 0 24 78 69 34 67 64 62 58 41 ]
 j = 4 交换: 3,4
L.key  [ 0 24 78 34 69 67 64 62 58 41 ]
 j = 3 交换: 2,3
L.key  [ 0 24 34 78 69 67 64 62 58 41 ]
 -------------------------进行 i = 3 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 24 34 78 69 67 64 62 41 58 ]
 j = 8 交换: 7,8
L.key  [ 0 24 34 78 69 67 64 41 62 58 ]
 j = 7 交换: 6,7
L.key  [ 0 24 34 78 69 67 41 64 62 58 ]
 j = 6 交换: 5,6
L.key  [ 0 24 34 78 69 41 67 64 62 58 ]
 j = 5 交换: 4,5
L.key  [ 0 24 34 78 41 69 67 64 62 58 ]
 j = 4 交换: 3,4
L.key  [ 0 24 34 41 78 69 67 64 62 58 ]
 -------------------------进行 i = 4 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 24 34 41 78 69 67 64 58 62 ]
 j = 8 交换: 7,8
L.key  [ 0 24 34 41 78 69 67 58 64 62 ]
 j = 7 交换: 6,7
L.key  [ 0 24 34 41 78 69 58 67 64 62 ]
 j = 6 交换: 5,6
L.key  [ 0 24 34 41 78 58 69 67 64 62 ]
 j = 5 交换: 4,5
L.key  [ 0 24 34 41 58 78 69 67 64 62 ]
 -------------------------进行 i = 5 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 24 34 41 58 78 69 67 62 64 ]
 j = 8 交换: 7,8
L.key  [ 0 24 34 41 58 78 69 62 67 64 ]
 j = 7 交换: 6,7
L.key  [ 0 24 34 41 58 78 62 69 67 64 ]
 j = 6 交换: 5,6
L.key  [ 0 24 34 41 58 62 78 69 67 64 ]
 -------------------------进行 i = 6 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 24 34 41 58 62 78 69 64 67 ]
 j = 8 交换: 7,8
L.key  [ 0 24 34 41 58 62 78 64 69 67 ]
 j = 7 交换: 6,7
L.key  [ 0 24 34 41 58 62 64 78 69 67 ]
 -------------------------进行 i = 7 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 24 34 41 58 62 64 78 67 69 ]
 j = 8 交换: 7,8
L.key  [ 0 24 34 41 58 62 64 67 78 69 ]
 -------------------------进行 i = 8 趟排序------------------------------------------------- 
 j = 9 交换: 8,9
L.key  [ 0 24 34 41 58 62 64 67 69 78 ]
 ----------------------------------升序冒泡L---------------------------------------- 
L.key  [ 0 24 34 41 58 62 64 67 69 78 ]

进程已结束,退出代码0

アルゴリズムの分析

① 時間計算量:

  • 最良のケース: 最初の正の順序、1 回の並べ替え、並べ替えプロセス中に n-1 個のキーワード比較が行われ、レコードは移動されません。
  • 最悪の場合: 最初の逆順、n-1 のソート、キーワード比較の合計数 KCN およびレコード移動数 RMN (各交換には 3 レコードの移動が必要) は次のとおりです: (n-1)+(n- 2 )+…
    ( 3-1)+(2-1) = n ( n − 1 ) 2 \frac{n(n-1)}{2}2n ( n 1 )
    工業団地 ≈ n 2 2 \frac{n^2}{2}2n2
    3[(n-1)+(n-2)+…(3-1)+(2-1)] = 3 [ n ( n − 1 ) 2 ] 3[\frac{n(n-1)} {2}]3 [2n ( n 1 )]
    RMN ≈3 n 2 2 3 \frac{n^2}{2}32n2
    時間計算量 O(n^2)

② スペース複雑さ:
バブル ソートでは、2 つのレコードの位置が交換されるときに一時レコード用の補助スペースのみが必要となるため、スペース複雑さは O(1) です。

【アルゴリズムの特徴】

① 安定したソート
② 連鎖ストレージ構造に使用可能
③ 移動するレコード数が比較的多く、アルゴリズムの平均時間パフォーマンスは直接挿入ソートよりも劣ります。最初のレコードの順序が正しくなく、n が比較的大きい場合、このアルゴリズムは使用すべきではありません。

おすすめ

転載: blog.csdn.net/QQ657205470/article/details/127738548