归并排序

参考资料:
http://www.cnblogs.com/jingmoxukong/p/4308823.html
http://blog.csdn.net/morewindows/article/details/6678165/

1、算法思路

(a)两个有序的数组合并

比如这两个升序数组

array1= 1 3 5 6 7,
array2= 2 4 8 9 10,

现要将array1和array2合并成一个升序的数组(),怎么合并呢?

通俗讲,就两点
(1)两个指针(这里用下标)指针两个升序数组首部,一个指针指向要合并到的数组temp首部。比较指向数据的大小,谁小就赋值到temp数组中,随后指针相应自加;
(2)当一个数组的值赋完了时,另一个就直接将剩下的数直接按顺序赋值到temp中;

看下面代码

int p_array1 = 0, p_array2 = 0,p_temp=0;
int temp[10];//array1 array2 合并到这个数组中

while (p_array1 < 5 && p_array2 < 5)
{
    if (array1[p_array1] < array2[p_array2])
        temp[p_temp++] = array1[p_array1++];
    else
        temp[p_temp++] = array1[p_array2++];
}

while (p_array1 < 5)
    temp[p_temp++] = array1[p_array1++];

while (p_array2 < 5)
    temp[p_temp++] = array2[p_array2++];

(b)归并归并,先递“归”拆分排序,之后合“并”。突然有点事,先挖坑。。

3、Test程序

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

void mergeArray(int *data, int first, int mid, int last, int *temp);
void mergeSortRecursion(int *data, int first, int last, int* temp);
bool mergeSort(int *data, unsigned int length);

void main(void)
{
    int array[20] = {6,1,2,8,10,4,3,9,5,7,15,12,13,16,14,17,19,11,20,18};
    int num = 20;

    //step1: 遍历数组,输出初始排列
    cout << "The original array: \n\t";
    for (int arN = 0; arN < num; arN++)
    {
        cout << array[arN]<<' ';
    }
    cout << endl;

    //step2: 归并排序
    mergeSort(array, num);

    //step3: 遍历数组,输出排序后结果
    cout << "After mergeSort: \n\t";
    for (int arN = 0; arN < num; arN++)
    {
        cout << array[arN]<<' ';
    }
    cout << endl;
}

//****************************//
//合并两个有序数组为一个有序数组
//****************************//
void mergeArray(int *data, int first, int mid,int last,int *temp)
{
    int p_new = 0, p_FM = first, p_ML = mid + 1;

    //如果有两组有序数组需要合并的话,就进行比较后合并到temp中
    while (p_FM <= mid&&p_ML <= last)
    {
        if (data[p_FM] < data[p_ML])
            temp[p_new++] = data[p_FM++];
        else
            temp[p_new++] = data[p_ML++];
    }

    //只剩一组有序数组的话,就依次并到temp队尾
    while (p_FM<=mid)
    {
        temp[p_new++] = data[p_FM++];
    }
    while (p_ML<=last)
    {
        temp[p_new++] = data[p_ML++];
    }

    //再把合并好了的新有序数组赋值到原数组中
    for (int i = 0; i < p_new; i++)
    {
        data[first + i] = temp[i];
    }

}

//****************************//
//归并排序中的递归操作(核心)
//*************************** //
void mergeSortRecursion(int *data, int first, int last, int* temp)
{
    if (first < last)
    {
        int mid = (first + last) / 2;

        //左二分之一部分做递归, "递"到只有一个数为一组时,运行mergeArray进行排序
        //接着再一步步"归"回来排序,最终左边序列排序完成
        mergeSortRecursion(data, first, mid, temp);

        //左二分之一部分排序完成后才会进行右二分之一的排序
        //同样,递到只有一个数为一组时,再"归"回来排序,最终序列排序完成
        mergeSortRecursion(data, mid + 1, last, temp);

        //最终归回来,将左二分之一部分和右二分之一部分进行"归并"
        mergeArray(data, first, mid, last, temp);
    }
}

//***********************************************************//
//归并排序的外部封装,
//和mergeSortRecusion主要区别是在这里提供一个临时temp方便合并序列
//***********************************************************//
bool mergeSort(int *data, unsigned int length)
{
    if (data == NULL)
        return false;

    int *temp = new int[length];
    if (temp == NULL)
        return  false;

    mergeSortRecursion(data, 0, length - 1, temp);

    delete[] temp;
    return true;
}

运行结果:
运行结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值