算法学习(排序二)归并排序

来源:互联网 发布:如何成为淘宝分销商 编辑:程序博客网 时间:2024/05/20 12:22

归并排序所采用的思想是分治法,即:分解 ->解决->合并
假设面对一个无序的数组,如{5, 19, 6, 97, 12, 53, 12, 21, 47, 10},将其分解为左右两个数组,但此时这两个数组还是无序的,因此,还需要进一步的分解,经过若干步之后,分解后如下所示
{{5}, {19}, {6}, {97}, {12}, {53}, {12}, {21}, {47}, {10}
当每个数组中仅有一个元素的,可以认为此数组是有序的,接下来,这些数组两两合并,最后一个组合成一个完整的有序数组

/** array数组中,left到mid和mid+1到right的部分都是已经排序好的,该函数的作用是将其重新排列为顺序数组 @param array 需要排序的数组 @param left 左边坐标 @param mid 中间坐标 @param right 右边坐标 */void Merges (int *array, int left, int mid, int right){    //TODO 1.获取左右两侧的长度    int leftNum = mid - left;    int rightNum = right - mid - 1;    //TODO 2.创建两个数组来保存左右两边的数据,数组长度为上面获取的长度加1    int leftArray[mid - left + 2];    int rightArray[right - mid + 1];    //TODO 3.从array中取出数据放入左右两个数组中    for (int i = 0; i <= leftNum; i++)        leftArray[i] = array[left + i];    for (int i = 0; i <= rightNum; i++)        rightArray[i] = array[mid + 1 + i];    //TODO 4.两个数组的最后一位设置为最大数    leftArray[leftNum + 1] = INT_MAX;    rightArray[rightNum + 1] = INT_MAX;    //TODO 5.添加索引    int leftIndex = 0;    int rightIndex = 0;    //TODO 6.将左右数组中的数进行比较后重新放入array中,哪一个数组大,则该数组的索引加1    for (int i = left; i <= right; i++) {        if (leftArray[leftIndex] < rightArray[rightIndex]) {            array[i] = leftArray[leftIndex];            leftIndex++;        }        else {            array[i] = rightArray[rightIndex];            rightIndex++;        }    }}/** 该函数的作用是分解一个数组 @param array 需要分解的数组 @param left 左边坐标 @param right 右边坐标 */void Mergesort (int *array, int left, int right){    //TODO 1.只有当left小于right时才可以进行下一步    if (left < right)    {        //TODO 2.获取中点        int mid = (left + right) / 2;        //TODO 3.继续分解,知道每个数组中仅有一个元素位置,此时默认该数组为有序的,才可以进行合并        Mergesort(array, left, mid);        Mergesort(array, mid + 1, right);        //TODO 4.将两个有序的数组合并        Merges(array, left, mid, right);    }}
原创粉丝点击