【数据结构】排序算法之归并排序

基本思想:将待排序的元素序列分成两个等长的子序列,再将子序列划分子序列,直到子序列中只有一个元素就不用在对子序列继续进行划分,将划分的每个区块,进行排序,然后再将其归并到一个序列中,直到将所有的子序列归并完成之后,则这个序列就完成了排序。
1、基本思想如下所示:
这里写图片描述

经过上面的划分,从而可以看出经过划分与归并,使得元素就有序。
但是要使得两个区间的元素能归并到一个区间中,如果只是将一个元素搬移到另一个区间,势必会造成数据溢出的情况,因此,借助辅助空间,完成每一次的排序即可。

代码如下所示:;

void _MegreSort(int *array, int left, int right, int* tmp);
void MegreSort(int *array, int size)
{
    assert(array || size < 0);
    //开辟临时空间
    int *tmp = new int[size];
    _MegreSort(array, 0, size, tmp);
    delete[] tmp;
}
void _Megre(int *array, int left,int mid, int right, int* tmp)
{
    //用来标记两个数组的下标
    int index1 = left;
    int index2 = mid;

    int index = left;
    //类似于链表合并
    while (index1 < mid&&index2 < right)
    {
        if (array[index1] < array[index2])
        {
            tmp[index++] = array[index1++];
        }
        else
        {
            tmp[index++] = array[index2++];
        }
    }
    //出来之后,如果哪个数组不为空,即将其元素直接搬移下来
    while (index1 < mid)
    {
        tmp[index++] = array[index1++];
    }
    while (index2 < right)
    {
        tmp[index++] = array[index2++];
    }
    //加空间中的元素直接拷贝下来
    memcpy(array+left, tmp+left, (right - left)*sizeof(int));
}
void _MegreSort(int *array, int left,int right,int* tmp)
{

    //当分块的区间中只有一个元素之时
    if (right - left <= 1)
        return;
    if (right > left)
    {
        int mid = left + ((right - left) >> 1);
        _MegreSort(array, left, mid, tmp);
        _MegreSort(array, mid, right, tmp);
        _Megre(array, left, mid, right, tmp);;
    }

}

2、方法二,非递归
这里写图片描述

代码如下所示:

void MegreSortNor(int *array, int size)
{
    int *tmp = new int[size];
    int gap = 1;
    while (gap < size)
    {
        for (int i = 0; i < size; i += 2*gap)
        {
            int left = i;
            int mid = i + gap;
            int right = mid + gap;//给出下一个区间中的元素

            //防止mid与right越界
            if (mid > size)
                mid = size;
            if (right > size)
                right = size;
            _Megre(array, left, mid, right, tmp);
        }
        gap *= 2;
    }
    delete[] tmp;
}

有关归并排序,就这么多了,希望大家一起学习!!!

只有不停的奔跑,才能不停留在原地!!!

猜你喜欢

转载自blog.csdn.net/aaronlanni/article/details/80087137