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