排序-归并排序

来源:互联网 发布:淘宝三无产品如何投诉 编辑:程序博客网 时间:2024/06/05 09:05

并归排序

这是从算法导论上截下来的

这里是代码

#include<iostream>using namespace std;void MergeSort(int *arr, int start, int end);void Merge(int *arr, int start, int middle, int end);int main(){    int arr[] = {6,9,8,7,5,2,1,43,0,5,6,9,8,5,4,1,2,3,23,14,56};    int len = sizeof(arr)/sizeof(arr[0]);    for(int i = 0; i < len; ++i)    {        cout<<arr[i]<<' ';    }    cout<<endl;    MergeSort(arr, 0, len-1);    for(int i = 0; i < len; ++i)    {        cout<<arr[i]<<' ';    }    cout<<endl;    return 0;}void Merge(int *arr, int start, int middle, int end){    int lengthleft = middle - start + 1;//第一个数组的长度    int lengthright = end - middle;//第二个数组的长度    int *left = new int[lengthleft];//开辟第一个数组    int *right = new int[lengthright];//开辟第二个数组    for(int i = 0; i < lengthleft; ++i)//复制到新的空间中    {        left[i] = arr[start+i];    }    for(int i = 0; i < lengthright; ++i)//复制到新的空间中    {        right[i] = arr[middle+1+i];    }    int indexleft = 0;    int indexright = 0;    int i = start;    //将元素重新放回原来的数组中    while (indexright < lengthright && indexleft < lengthleft)    {        if(left[indexleft] <= right[indexright])        {            arr[i++] = left[indexleft++];        }        else        {            arr[i++] = right[indexright++];        }    }    while (indexright == lengthright && indexleft < lengthleft)    {        arr[i++] = left[indexleft++];    }    while (indexleft == lengthleft && indexright < lengthright)    {        arr[i++] = right[indexright++];    }    //部分排序完成 合并结束    delete []left;    delete []right;    return;}void MergeSort(int *arr, int start, int end){    if(start < end)    {        int middle = (end+start) / 2 ;        //总个数除以2    5 -> 1 第二个     6 -> 2  第三个   最小2 -> 0  第一个        MergeSort(arr, start, middle);        MergeSort(arr, middle+1, end);        Merge(arr, start, middle, end);    }    return;}

备注

这次并归排序有几个坑需要注意一下:
1 关于start与middle与end几个下标的关系
要求start指向左数组的第一个下标
middle指向左数组的最后一个下标
end指向右数组的最后一个下标
middle可以与start相等
2 middle如何计算
之前试过
(start-end+1)/2
(start-end+1+1)/2
都不行 正确的计算公式是
(start + end)/2
这样才能保证第一个数组大于等于第二个数组
3 关于将两个新的空间中的元素有序合并放入原空间
在《算法导论》中看到它给每一个数组多开辟了一个空间
用来放置最哨兵(此元素为无穷大)从而简化了操作过程
4 归并排序是一个典型的运用了分治法的例子
因为每个小的数组是将原来的分解而成,所以空间复杂度为O(n)
时间复杂度为O(nlgn)