归并排序

递归实现

void merge(int a[],int asize,int b[],int bsize){  //合并两个已经有序数组
    int i = 0, j = 0, t=0, temp[MAXSIZE];
    while (i < asize&&j < bsize){
        if (a[i] < b[j]) temp[t++] = a[i++];
        else temp[t++] = b[j++];
    }
    while (i < asize) temp[t++] = a[i++];
    while (j < bsize) temp[t++] = b[j++];
    for (int k = 0; k < (asize + bsize); k++) a[k] = temp[k];
}
void mergesort(int queue[],int size){    //将数组分为两部分进行处理
    if (size <= 1) return;
    int *queue1 = queue;
    int que1size = size / 2;
    int *queue2 = queue + que1size;
    int que2size = size - que1size;
    mergesort(queue1, que1size);
    mergesort(queue2, que2size);
    merge(queue1, que1size, queue2, que2size);
}

迭代实现

递归实现在数组较大的情况下会出现“爆栈”(栈的深度为log₂N),为了避免出现这种情况尽量使用非递归的方式。

 

void mergesort(int queue[],int size){
    int index = 0, left_min, left_max, right_min, right_max;
    int temp[MAXSIZE];    //用于存储临时排好顺序的数组,index为temp下标
    for (int i = 1; i < size; i *= 2){        //最小的分组为1,每次二倍增加,模拟递归效果
        for (left_min = 0; left_min < size - i; left_min = right_max){    //left为左半边数组,right为右半边数组
            right_min = left_max = left_min + i;
            right_max = right_min + i;
            if (right_max>size) right_max = size;    //数组最大的范围是size
            while (left_min < left_max&&right_min < right_max){
                if (queue[left_min] < queue[right_min]) temp[index++] = queue[left_min++];
                else temp[index++] = queue[right_min++];
            }
            while (left_min < left_max) queue[--right_min] = queue[--left_max];    //与递归不同的是,左边剩余未合并的数组需要处理,但是右边的不需要,只需保持就好
            while (index>0) queue[--right_min] = temp[--index];    //将temp中的数组存在原数组中
        }
    }
}

 

posted @ 2018-04-07 22:39  Mr.Struggle  阅读(135)  评论(0编辑  收藏  举报