数据结构与算法——起泡排序与归并排序(C++)

1 绪论

初次基于向量实现起泡排序与归并排序,以为有所得,故记录下来。

2 整体程序

#include <iostream>
#include <vector>
using namespace std;

bool bubble( int* A, int lo, int hi);
void bubbleSort( int* A, int lo, int hi);
void mergeSort ( int *A, int lo, int hi);
void merge( int *&A, int lo, int mi, int hi );

int main()
{
    int A[] = { 4, 5, 3, 7, 12, 13, 0, 15};
    int size = sizeof(A)/sizeof(A[0]);
    int (&AA)[8] = A; //数组的引用
    //bubbleSort(A, 0, 7); 
    mergeSort (AA, 0, size);

    //输出排序结果
    for (int i = 0; i < size - 1;i++){
        cout << A[i] << ", ";
    }
    cout << A[size - 1] <<endl;

   
}
        
//起泡排序
void bubbleSort( int* A, int lo, int hi){
    while ( !bubble (A, lo, hi--));
}

bool bubble( int* A, int lo, int hi){
    bool sorted = true; //整体有序标志
    while (++lo < hi){
        if (A[lo - 1] > A[lo]){
            sorted = false;
            swap (A[lo -1 ], A[lo]);
        }
    }
    return sorted;
}


//归并排序
void mergeSort (int *A, int lo, int hi){
    if (hi - lo < 2) return;
    int mi = (lo + hi) / 2;
    mergeSort ( A, lo, mi); 
    //展示递归的过程(1)
    for (int i = lo; i < mi ;i++){
        cout << A[i] << ", ";
    }
    cout << "end0" << endl;

    mergeSort(A, mi, hi);
    //展示递归的过程(2)
    for (int i = mi; i < hi ;i++){
        cout << A[i] << ", ";
    }
    cout << "end1" << endl;

    merge(A, lo, mi, hi); //归并

}

void merge(int *&A, int lo, int mi, int hi ){//各自有序的向量[lo,mi)和[mi,hi)
    int* A1 = A + lo;              
    int lb = mi - lo;
    int* B1 = new int[lb];//前子向量B1[0,lb) = A[lo,mi)
    for ( int i = 0; i < lb; i++) B1[i] = A1[i];  //不能写成for ( int i = 0; i < lb; B1[i] = A1 [i++])
    int lc = hi - mi; int* C1 = A + mi;//后子向量C1[0, lc) = A[mi, hi)        
    for ( int i = 0, j = 0, k = 0; (j < lb)||(k < lc);){
        if((j < lb )&&(!(k < lc)||( B1[j] <= C1[k]))) A1[i++] = B1[j++];
        if((k < lc )&&(!(j < lb)||( C1[k] < B1[j]))) A1[i++] = C1[k++];
    }
    delete [] B1;
}



3 起泡排序

  • 作为最简单的排序方式之一,起泡排序采用减而治之的策略。每一个轮回之后,最大的值都会回到最末端,以此可以不断减小问题的规模。
//起泡排序
void bubbleSort( int* A, int lo, int hi){
    while ( !bubble (A, lo, hi--));
}

bool bubble( int* A, int lo, int hi){
    bool sorted = true; //整体有序标志
    while (++lo < hi){
        if (A[lo - 1] > A[lo]){
            sorted = false;
            swap (A[lo -1 ], A[lo]);
        }
    }
    return sorted;
}

4 归并排序

  • 归并排序的思想朴素而深沉,分而合之,正如“将欲取之,必须与之”,化整为零,然后可以成你所想
//归并排序
void mergeSort (int *A, int lo, int hi){
    if (hi - lo < 2) return;
    int mi = (lo + hi) / 2;
    mergeSort ( A, lo, mi); 
    //展示递归的过程(1)
    for (int i = lo; i < mi ;i++){
        cout << A[i] << ", ";
    }
    cout << "end0" << endl;

    mergeSort(A, mi, hi);
    //展示递归的过程(2)
    for (int i = mi; i < hi ;i++){
        cout << A[i] << ", ";
    }
    cout << "end1" << endl;

    merge(A, lo, mi, hi); //归并

}

void merge(int *&A, int lo, int mi, int hi ){//各自有序的向量[lo,mi)和[mi,hi)
    int* A1 = A + lo;              
    int lb = mi - lo;
    int* B1 = new int[lb];//前子向量B1[0,lb) = A[lo,mi)
    for ( int i = 0; i < lb; i++) B1[i] = A1[i];  //不能写成for ( int i = 0; i < lb; B1[i] = A1 [i++])
    int lc = hi - mi; int* C1 = A + mi;//后子向量C1[0, lc) = A[mi, hi)        
    for ( int i = 0, j = 0, k = 0; (j < lb)||(k < lc);){
        if((j < lb )&&(!(k < lc)||( B1[j] <= C1[k]))) A1[i++] = B1[j++];
        if((k < lc )&&(!(j < lb)||( C1[k] < B1[j]))) A1[i++] = C1[k++];
    }
    delete [] B1;
}
  • 下面是该程序运行出的结果,通过展示递归过程,可以帮助对归并的理解
    4, end0
    5, end1
    4, 5, end0
    3, end0
    7, end1
    3, 7, end1
    3, 4, 5, 7, end0
    12, end0
    13, end1
    12, 13, end0
    0, end0
    15, end1
    0, 15, end1
    0, 12, 13, 15, end1
    0, 3, 4, 5, 7, 12, 13, 15

5 总结

归并排序借鉴了邓俊辉老师的代码,没有用其中的模板。遇到了总是输出出错的问题。自己化整为零地分析一行行代码,来分析整个代码逻辑,最终终于找到了有问题的语句。通过这个过程,我对于归并的思想理解得更加深刻。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值