印象中这些排序的发生过程,写了一下从冒泡到归并排序的六个简单的排序代码。只有归并排序相对复杂一点,写了注释。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define ARR_SIZE 100000
int arr[ARR_SIZE];
void array_sort_print(int *arr, int size, void(*sort)(int*, int)); //排序处理包装函数
void bubble(int *arr, int size); //冒泡
void select(int *arr, int size); //选择
void insert(int *arr, int size); //插入
void shell(int *arr, int size); //shell
void merge(int *arr, int size); //归并
int main() {
for (int i = 0; i < ARR_SIZE; ++i) {
arr[i] = rand() % 10000;
}
const int size = sizeof(arr) / sizeof(arr[0]);
array_sort_print(arr, size, merge); //排序处理
return 0;
}
void merge(int *arr, int size) {
int* arr_copy1 = (int*)malloc(size * sizeof(int));
int* arr_copy2 = (int*)malloc(size * sizeof(int)); //辅助数组1,2
if (arr_copy1 == nullptr || arr_copy2 == nullptr)exit(1);
memcpy(arr_copy2, arr, size * sizeof(int));
for (int delta = 1; delta < size; delta *= 2) { //每段1个到每段size个
memcpy(arr_copy1, arr_copy2, size * sizeof(int)); //辅助数组2准备被归并覆盖
int pos = 0; //辅助数组中的当前数据位置
for (int j = 0; j < size; j += delta * 2) { //每段段内处理
int start1 = j;
int end1 = j + delta > size ? size : j + delta; //求出2段起始与终止
int start2 = end1 > size ? size : end1;
int end2 = start2 + delta > size ? size : start2 + delta;
while (start1 < end1 && start2 < end2) { //三大循环开始归并2个有序数组
arr_copy1[pos++] = arr_copy2[start1] < arr_copy2[start2] ? arr_copy2[start1++] : arr_copy2[start2++];
}
while (start1 < end1) {
arr_copy1[pos++] = arr_copy2[start1++];
}
while (start2 < end2) {
arr_copy1[pos++] = arr_copy2[start2++];
}
}
void* p_temp = arr_copy1; //交换
arr_copy1 = arr_copy2;
arr_copy2 = (int*)p_temp;
}
memcpy(arr, arr_copy2, size * sizeof(int));
free(arr_copy2);
free(arr_copy1);
}
void shell(int *arr, int size) {
int delta = size;
int i, j, temp;
while (delta /= 2) { //间隔先大后小,直到为0
for (i = delta; i < size; i += delta) {
temp = arr[i];
for (j = i - delta; j >= 0 && temp < arr[j]; j -= delta) {
arr[j + delta] = arr[j];
}
arr[j + delta] = temp;
}
}
}
void insert(int *arr, int size) {
int j, i, temp;
for (j = 1; j < size; ++j) {
temp = arr[j];
for (i = j - 1; i >= 0 && arr[i] > temp; --i) {
arr[i + 1] = arr[i];
}
arr[++i] = temp;
}
}
void select(int *arr, int size) {
int min_index = 0;
for (int j = 0; j < size; ++j) {
min_index = j;
for (int i = j + 1; i < size; ++i) {
if (arr[i] < arr[min_index]) {
min_index = i;
}
}
if (min_index != j) {
int temp = arr[j];
arr[j] = arr[min_index];
arr[min_index] = temp;
}
}
}
void bubble(int *arr, int size) {
for (int i = 0; i < size; ++i) {
int n = size - i - 1;
for (int j = 0; j < n; ++j) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void array_sort_print(int *arr, int size, void(*sort)(int*, int)) {
puts("Before sorting:");
for (int i = 0; i < size; ++i) {
printf("%d ", *(arr + i));
}
sort(arr, size); //排序处理
puts("\nAfter sorting:");
for (int i = 0; i < size; ++i) {
printf("%d ", *(arr + i));
}
}
相同排序10万个数,最慢的冒泡排序的整个程序全程41.7s,这里头最快的归并排序28.43s。不过因为Windows下输出到终端的过程是非常耗时,粗看一下,还是之后在linux下观察。