归并排序

来源:互联网 发布:网络用户的未来发展 编辑:程序博客网 时间:2024/06/08 14:01
/***********************************************************************
归并排序算法思想:
分而治之(divide - conquer);每个递归过程涉及三个步骤
第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.
第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作
第三, 合并: 合并两个排好序的子序列,生成排序结果.
************************************************************************/
/*
    9,    8,    7,     6,    5,    4,    3,    2,    1,    0
                                       |分割
   9,   8,   7,   6,   5                4,   3,   2,   1,   0
                |分割                                  |分割
  9,  8,  7      6,  5                  4,  3,  2      1,   0   
       |分割         |分割                     |分割         |分割
 9, 8     7     6      5               4,  3    2      1     0
   |分割                                  |分割          
 9   8    7     6      5              4     3   2      1     0  
   |归并            |归并                  |归并             |归并
  8,9    7        5,6                   3,4     2        0,1
       |归并                                  |归并
  7, 8, 9          5, 6                  2, 3, 4         0, 1
            |归并                                      |归并      
     5, 6, 7, 8, 9            0, 1, 2, 3, 4
                                         |归并
          0, 1, 2, 3, 4, 5, 6, 7, 8, 9
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

void TraversalArray(int array[], int len)
{
    assert(array != NULL);
    assert(len >= 0);

    unsigned int index = -1;

    for(index = 0; index < len; index++)
    {
        printf("%3d", array[index]);
    }

    printf("\n");
}

void Meger(int array[], int start, int mid, int end)
{
    assert(array != NULL);
    assert(start < end);

    int len1 = mid - start + 1;
    int len2 = end - mid;
    int left[len1], right[len2];/*建立两个临时数组,分别存储分解的两个子序列*/
    int i = 0, j = 0, index = start;

    for(i = 0; i < len1; i++)
    {
        left[i] = array[start + i];/*start->mid 存储到 left[]*/
    }

    for(j = 0; j < len2; j++)
    {
        right[j] = array[mid + 1 + j];/*mid+1->end 存储到 right[]*/
    }

    /*归并两个子序列,归并后的序列存储到原来的数组空间*/
    for(i=0, j=0; (i<len1) && (j<len2); index++)
    {
        if(left[i] < right[j])
        {
            array[index] = left[i++];
        }
        else
        {
            array[index] = right[j++];
        }
    }
/*
    while(i < len1)
    {
        array[index++] = left[i++];
    }

    while(j < len2)
    {
        array[index++] = right[j++];
    }
*/

    if(i < len1)
    {
        memcpy(array+index, left+i, (len1-i)*sizeof(array[0]));
    }

    if(j < len2)
    {
        memcpy(array+index, right+j, (len2-j)*sizeof(array[0]));
    }

}

void MegerSort(int array[], int start, int end)
{
    assert(array != NULL);
    
    int mid = -1;
    if(start < end)
    {
        mid = (start + end) / 2;
        
        MegerSort(array, start, mid);
        MegerSort(array, mid + 1, end);
        Meger(array, start, mid, end);
    }
}

int main(void)
{
    int array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};

    TraversalArray(array, sizeof(array)/sizeof(array[0]));

    MegerSort(array, 0, sizeof(array)/sizeof(array[0])-1);

    TraversalArray(array, sizeof(array)/sizeof(array[0]));

    return    0;
}
0 0
原创粉丝点击