您的位置:首页 > 其它

算法 排序算法之归并排序

2017-06-03 22:40 309 查看

归并排序

归并排序主要是二路归并排序

基本思想

设数组a中存放了n个数据元素

初始时把它们看成n个长度为1的有序子数组,然后从第一个子数组开始,把相邻子数组两两合并,得到n/2的整数上界个长度为2的新的有序子数组(当n为奇数时最后一个新的有序子数组的长度为1)

对这些新的有序子数组再两两合并,直到最后长度为n的有序数组位置

排序过程



以数组{50,10,90,30,70,40,80,60,20}为例



代码实现

void Merge(DataType a[], int n, DataType swap[], int k) {
/*k为有序子数组的长度,一次二路归并排序后的有序子序列放在数组swap中*/
int m = 0, u1, l2, i, j, u2;

/*第一个有序子数组下界为0*/
int l1 = 0;
while (l1 + k <= n - 1) {
l2 = l1 + k;//计算第二个有序子数组下界
u1 = l2 - 1;//计算第一个有序子数组上界
u2 = (l2 + k - 1 <= n - 1) ? l2 + k - 1 : n - 1;//计算第二个有序子数组上界

/*两个有序子数组合并*/
for (i = l1, j = l2; i <= u1 && j <= u2; m++) {
if (a[i] <= a[j]) {
swap[m] = a[i];
i++;
} else {
swap[m] = a[j];
j++;
}
}

/*子数组2已归并完,将数组1中剩余的元素放到数组swap中*/
while (i <= u1) {
swap[m] = a[i];
m++;
i++;
}

/*子数组1已归并完,将数组2中剩余的元素放到数组swap中*/
while (j <= u2) {
swap[m] = a[j];
m++;
j++;
}
l1 = u2 + 1;
}
/*将原始数组中只够一组的元素顺序放到数组swap中*/
for (i = l1; i < n; i++, m++) {
swap[m] = a[i];
}
}


void MergeSort(DataType a[], int n) {
int i, k = 1;//归并长度从1开始
DataType * swap;

swap = (DataType *) malloc(sizeof(DataType) * n);

while (k < n) {
Merge(a, n, swap, k);
for (i = 0; i < n; i++) {
a[i] = swap[i];
}
k = 2 * k;
}
free(swap);
}


java实现

public static void mergeSort(int[] arr) {
mergeSort(arr, 0, arr.length - 1);
}

private static void mergeSort(int[] arr, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
//左边
mergeSort(arr, low, mid);
//右边
mergeSort(arr, mid + 1, high);
//左右归并
merge(arr, low, mid, high);
}
}

private static void merge(int[] arr, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int left = low;//左指针
int right = mid + 1;//右指针
int k = 0;
//把较小的数先移动到新数组中
while (left <= mid && right <= high) {
if (arr[left] < arr[right]) {
temp[k++] = arr[left++];
} else {
temp[k++] = arr[right++];
}
}
//把左边剩余的数移入数组
while (left <= mid) {
temp[k++] = arr[left++];
}

//把右边剩余的数移入数组
while (right <= high) {
temp[k++] = arr[right++];
}

//把新数组中的数覆盖nums数组
for (int k2 = 0; k2 < temp.length; k2++) {
arr[k2 + low] = temp[k2];
}
}


算法分析

时间复杂度

一次二路归并排序归并的次数log2n 每次比较次数n-1 故时间复杂度是O(nlog2n)

空间复杂度

使用了n个临时内存单元存放数据 空间复杂度O(n)

稳定性

归并排序是一种比较占内存,但却效率高且稳定的算法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: