归并排序的算法很简单,它的原理是将两个或两个以上的有序表合成一个新的有序表。假设有n个待排序记录,我们即可将其看成是n个有序的子表,每个子表的长度为1。我们对它们进行两两归并,得到 个长度为2或为1的有序子表,再对它们进行两两归并,直到整个数组成为一个有序表为止。
#include <stdio.h> #include <stdlib.h> #include <math.h> #define SIZE (10) //显示数组 void display(int *array, int size) { for (int i = 0; i < size; i++) { printf("%d ", array[i]); } printf("\n"); } //两个相邻的有序序列归并成一个有序序列 //in[x]~in[y]和in[y+1]~in[z]合并 void merge(int *in, int *out, int x, int y, int z) { int t, i, j; //依次从两个有序子表中取得较小的关键字加入out数组中 for (t = x, i = x, j = y + 1; i <= y && j <= z; t++) { //取得较小的关键字加入out数组中 if (in[i] < in[j]) { out[t] = in[i++]; } else { out[t] = in[j++]; } } //将第1个子表中未完成的元素追加到out while (i <= y) { out[t++] = in[i++]; } //将第2个子表中未完成的元素追加到out while (j <= z) { out[t++] = in[j++]; } } //归并排序 void merging_sort(int *array, int size) { //临时数组 int temp[size]; //步长 int step = 1; //归并趟数 int t = 0; //多趟归并 for (t = 0; step < size; t++) { //每趟归并将数组分为n/2(向上取整)个组 for (int i = 0; i < size; i += step * 2) { //计算第1个有序子表的结束位置 int e = i + step; if (e >= size) { e = size - 1; } //计算第2个有序子表的结束位置 int end = e + step - 1; if (end >= size) { end = size - 1; } //由array向temp中归并 if (t % 2 == 0) { merge(array, temp, i, e - 1, end); } //由temp向array中归并 else { merge(temp, array, i, e - 1, end); } } //步长乘2 step *= 2; if (t % 2 == 0) { display(temp, size); } else { display(array, size); } } //如果经过了奇数次并归,说明结果放在了temp中 if (t % 2 != 0) { //将temp元素复制到array中 for (int i = 0; i < size; i++) { array[i] = temp[i]; } } } int main(int argc, char **args) { int array[SIZE] = { 5, 3, 7, 2, 9, 8, 1, 0, 6, 4 }; display(array, SIZE); merging_sort(array, SIZE); return 0; }
运行结果:
原数组 5 3 7 2 9 8 1 0 6 4 第1趟归并 3 5 2 7 8 9 0 1 4 6 第2趟归并 2 3 5 7 0 1 8 9 4 6 第3趟归并 0 1 2 3 5 7 8 9 4 6 第4趟归并 0 1 2 3 4 5 6 7 8 9
本例代码:
code path chapter.08/e.g.8.7/ https https://github.com/magicworldos/datastructure.git git git@github.com:magicworldos/datastructure.git subverion https://github.com/magicworldos/datastructure
Copyright © 2015-2023 问渠网 辽ICP备15013245号