排序算法-归并排序

二路归并排序主旨是“分解”与“归并”

分解:

1.将一个数组分成两个数组,分别对两个数组进行排序。

2.循环第一步,直到划分出来的“小数组”只包含一个元素,只有一个元素的数组默认为已经排好序。

归并:

1.将两个有序的数组合并到一个大的数组中。

2.从最小的只包含一个元素的数组开始两两合并。此时,合并好的数组也是有序的。

图1. 归并排序过程
图2. 合并两个有序数组

举例说明:

1.图中原始数组为{2,4,7,5,8,1,3,6},数组中元素的个数为8个。首先将8个元素的数组二分,每次分解后,

数组中元素的数目为原数组的一半。直到分解为只含有一个元素的数组。

2.将小的数组按序合并,每次合并后数组的大小为上层数组的一倍。此时数组中的元素都是按序排列的。

3.在合并两个有序数组。如图2

void  merge(int * a, int low, int mid, int high)
{
    int i = low, j = mid + 1, p = 0;//对应a数组的下标
    int  r[high - low + 1];//申请另一个对应大小的数组来存放排好序的数据
    while (i <= mid && j <= high)
    {
        r[p++] = (a[i] <= a[j]) ? a[i++] : a[j++];
    }
    while (i <= mid)
        r[p++] = a[i++];
    while (j <= high)
        r[p++] = a[j++];
    for (p = 0, i = low; i <= high; p++, i++)
        a[i] = r[p];//最后再把有序数据存进a数组中,使得a数组对应部分数据有序
}

void mergeSort(int k[], int low, int high) {
    if (low < high) {
        int mid = (low + high) / 2;
        mergeSort(k, low, mid); //归并排序前半段
        mergeSort(k, mid + 1, high); // 归并排序后半段
        
        merge(k, low, mid, high);
    }
}

迭代实现

#define MAXSIZE 10

void MergeSort(int k[], int n)
{
    int i, next, left_min, left_max, right_min, right_max;
    int *temp = (int *)malloc(n * sizeof(int));

    for( i=1; i < n; i*=2 ) 
    {
        for( left_min=0; left_min < n-i; left_min = right_max )
        {
            right_min = left_max = left_min + i;
            right_max = left_max + i;

            if( right_max > n )
            {
                right_max = n;
            }

            next = 0;

            while( left_min < left_max && right_min < right_max )
            {
                if( k[left_min] < k[right_min] )
                {
                    temp[next++] = k[left_min++];
                }
                else
                {
                    temp[next++] = k[right_min++];
                }
            }

            while( left_min < left_max )
            {
                k[--right_min] = k[--left_max];
            }

            while( next > 0 )
            {
                k[--right_min] = temp[--next];
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 归并排序 思路:使用分治思想,将数组一直拆分,直到拆分成一个元素,此时每一个元素都相当于一个有序的数组,之后再将每...
    守敬阅读 524评论 0 1
  • 归并排序是一种效率比较高的排序算法,但是它额外需要一个和需要排序的数组同样大小的空间。但是在时间和空间进行取舍,我...
    我有一只碗阅读 149评论 0 0
  • 对于经典算法,你是否也遇到这样的情形:学时觉得很清楚,可过阵子就忘了? 本系列文章就尝试解决这个问题。 研读那些排...
    pansly阅读 1,187评论 0 1
  • 上篇文章说的是快速排序,这篇文章将归并排序。 归并排序和快速排序的思路有类似的地方,都是二分思想+递归调用的思路。...
    西经使徒阅读 102评论 0 1
  • 归并排序和快速排序都用到了分治思想,非常巧妙。我们可以借鉴这个思想,来解决非排序的问题。 归并排序 归并排序的核心...
    被吹落的风阅读 1,368评论 0 3