归并排序 tips && codes

来源:互联网 发布:淘宝现在是什么模式 编辑:程序博客网 时间:2024/06/05 05:52

归并是O(NlogN)里比较快的,通常速度非常接近快排。思想也是分治。

比如现在有a[0~n]需要排序

tips:1.先让a[1 ~ n/2]和a[1 ~ n/2 + 1]分别有序,回溯的时候再合并起来;

 2.既然左右两半都各自有序,那么比较其各自第一个元素大小,并不断插入到一个临时数组里即可;

while(i <= mid && j <= right){if (a[i] < a[j]){tmp[k++] = a[i++];}elsetmp[k++] = a[j++];}while(i <= mid){tmp[k++] = a[i++];}while(j <= right){tmp[k++] = a[j++];}
这里k = right - left, 即本次被合并的俩子数列的总长。

 3.递地划分数列,再合起来。递归终止于数列只存在1个元素,即left == right的情况。

void mergesort(int a[], int left, int right, int tmp[]){if (left < right){int mid = (left + right) / 2;mergesort(a, left, mid, tmp);mergesort(a, mid+1, right, tmp);merge(a, left, mid, right, tmp);}}

 4.白话经典算法中为了省掉每次分配临时数组的时间,在最上层统一分配了一个大tmp数组,送进程序。


完整codes:

#include <iostream>using namespace std;void merge(int a[], int left, int mid, int right, int tmp[]){int i, j, k;k = 0;i = left;j = mid + 1;while(i <= mid && j <= right){if (a[i] < a[j]){tmp[k++] = a[i++];}elsetmp[k++] = a[j++];}while(i <= mid){tmp[k++] = a[i++];}while(j <= right){tmp[k++] = a[j++];}for (i = 0; i < k; ++i){a[left + i] = tmp[i];}}void mergesort(int a[], int left, int right, int tmp[]){if (left < right){int mid = (left + right) / 2;mergesort(a, left, mid, tmp);mergesort(a, mid+1, right, tmp);merge(a, left, mid, right, tmp);}}bool Mergesort(int a[], int n){int* tmp = new int[n];if (tmp == NULL){return false;}mergesort(a, 0, n-1, tmp);delete[] tmp;return true;}int main(void){int a[] = {2,4,5,6,1,9,10,3,8,7};Mergesort(a, 10);for (int i = 0; i < 10; ++i){cout << a[i] << endl;}return 0;}


0 0
原创粉丝点击