归并排序

来源:互联网 发布:战锤全面战争 知乎 编辑:程序博客网 时间:2024/06/18 17:54

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。讲已有有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序。

归并操作的工作原理(将二个有序数列合并):

第一步:申请空间,使其大小为已经排序序列之和,该空间用来存放合并后的序列。

第二步:设定两个指针,最初为之分,最初位置分别为两个已经排序序列的起始位置。

第三步:比较两个指针所指向的元素,选择相对较小的元素放入到合并空间,并移动指针到下一位置。

重复步骤3一直到有一指针超出序列尾,将另一序列剩下的所有元素直接复制到合并序列尾。

#include<iostream>#include<cstdio>using namespace std;void MERGE(int a[], int p, int q, int r){    int i = p, j = q +1, k = p, b[100];    while(i!=q+1 && j!=r+1)    {        if(a[i] < a[j])            b[k++] = a[i++];        else            b[k++] = a[j++];    }    while(i!=q+1)        b[k++] = a[i++];    while(j!=r+1)        b[k++] = a[j++];    for(i=p;i<=r;i++)        a[i] = b[i];}int main(){    int a[10] = {1,3,5,7,9,2,4,6,8,10};    MERGE(a, 0, 4, 9);    for(int i = 0;i<10;i++)        cout << a[i] << endl;    return 0;}

这样就实现了把两个排序好的数组合并成一个有序的数组了。

那么归并排序的思路其实就是将数组分成两组,若是这两组有序我们可以很快将这两个数组合并成一个有序的数组。我们可以将分出来的这两组每一组继续分成两组,就这样递归下去,当分出来的小组只有一个数据的时候,这是我们认为它是有序的,然后一次合并相邻的二个数组。这样便完成了归并排序:

#include<iostream>#include<cstdio>using namespace std;void MERGE(int a[], int b[], int p, int q, int r){    int i = p, j = q +1, k = p;    while(i!=q+1 && j!=r+1)    {        if(a[i] < a[j])            b[k++] = a[i++];        else            b[k++] = a[j++];    }    while(i!=q+1)        b[k++] = a[i++];    while(j!=r+1)        b[k++] = a[j++];    for(i=p;i<=r;i++)        a[i] = b[i];}void MERGESORT(int a[], int b[], int p, int r){    int q;    if(p < r)    {        q = (p + r) / 2;        MERGESORT(a, b, p, q);        MERGESORT(a, b, q+1, r);        MERGE(a, b, p, q, r);    }}int main(){    int a[10] = {5, 4, 9, 2, 8, 0, 7, 1, 3, 10};    int b[10];    MERGESORT(a, b, 0, 9);    for(int i=0;i<10;i++)        cout << a[i] << endl;    return 0;}

归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。


0 0
原创粉丝点击