经典排序之归并排序

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

/**

    分治法排序:

    1、分解。2、解决。3、合并。

**/



void merge(int* a,int p,int q,int r)

{

    int i,j;

    for(i=p,j=q; i<q && j<r;)

    {

        if(a[i] <= a[j])

        {

            i++;

            continue;

        }else

        {

            int k;

            int tem = a[j];

            for(k = j; k > i; k--)

            a[k] = a[k-1];

            a[k] = tem;

            j++;

            i++;//

            q++;//注意这里移动了i,那么q也要一起移动~~

        }

    }

}



void divide(int* a,int length)

{

    if(length > 1 )

    {

        int v = length/2;

        divide(a,v);

        divide(a+v,length-v);

        merge(a,0,v,length);

    }

}



int main()

{

    int A[] = {3,41,52,26,38,57,9,49,1,55,45,5,6,49};

    int length = sizeof(A)/sizeof(int);



    for(int i = 0; i < length; i++)

    printf("%d ",A[i]);

    printf("\n");



    divide(A,length);



    for(int i = 0; i < length; i++)

    printf("%d ",A[i]);

    printf("\n");

    return 0;

}

归并排序想法很简单,类似于分治法,先将一个长长的序列分成若干子序列,然后合并,其核心就在于合并过程。算法导论中这样描述:想象一下桌子上放好了两副排好顺序的扑克,然后要把这两副扑克合并成一幅排好顺序的扑克,那么就分别从两副扑克的最上边取最小的然后组成一个新的序列。取完之后即完成了排序。归并排序就是利用这个思想。

注意点:1、数组模仿时,注意当数组元素移动时,移动标志位。

你可能感兴趣的:(归并排序)