常用排序算法之归并排序

来源:互联网 发布:围棋 人工智能算法 编辑:程序博客网 时间:2024/06/06 02:25

归并排序

  • 基本思想

取两个输入数组A和B,一个输出数组C,以及三个计数器Aptr,Bptr,Cptr,计数器开始都被置于对应数组的开始端。A[Aptr]和B[Bptr]中的较小者被拷贝到C中的下一个位置,相关的计数器向前推进一步。当A和B俩个表中有一个用完时,则将另一个表中剩下的部分拷贝到C中。

归并排序是递归算法的很好的实例,也是经典的分治策略。将问题分解为一些较小的问题然后递归求解,治的阶段则将分阶段的解得的各个答案修补到一起。

我们将数组A中的1,13,24,26,2,15,27,38这8数用归并排序进行排序。

现将数组A一分为二,24,1,26,13为左组。27,15,38,2为右组,再格外使用一个临时数组C用来存放最终结果。

先将左组中的数据递归进行排序,再将右组中的数据递归进行排序,最后将俩组数据进行合并。

  • 程序实现

#include<iostream>using namespace std;void print(int a[], int n){      for(int j= 0; j<n; j++)    {          cout<<a[j] <<" ";      }      cout<<endl;  }  void mergearray(int a[], int first, int mid, int last, int temp[])  {      int i = first, j = mid + 1;  //俩个指针,i左边数组的指针。j右边数组的指针    int m = mid,   n = last;  //m左边数组的边界,n右边数组的边界    int k = 0;            while (i <= m && j <= n)      {          if (a[i] <= a[j])  //总是将每半边中较小的一个数赋值给temp。            temp[k++] = a[i++];          else              temp[k++] = a[j++];      }            while (i <= m)          temp[k++] = a[i++];            while (j <= n)          temp[k++] = a[j++];            for (i = 0; i < k; i++)          a[first + i] = temp[i];  //重新将temp赋值给a}  void mergesort(int a[], int first, int last, int temp[])  {      if (first < last)      {          int mid = (first + last) / 2;          mergesort(a, first, mid, temp);    //左边有序          mergesort(a, mid + 1, last, temp); //右边有序          mergearray(a, first, mid, last, temp); //再将二个有序数列合并          print(a, 8);    }  }    bool MergeSort(int a[], int n)  {      int *p = new int[n];      if (p == NULL)          return false;      mergesort(a, 0, n - 1, p);      delete[] p;      return true;  } int main(){    int a[8]={24,1,26,13,27,15,38,2};    MergeSort(a, 8);    system("pause");}

  • 程序实现分析:

MergeSort(a, 8);将数组a中的8个数进行排序。

1:开始

mergesort(a, 0, 7, p); 第一个数是a[0],第二个数是a[7],mid为3,

first < last 

递归调用左边:mergesort(a, 0, 3, p);右边:mergesort(a, 4, 7, p);

2::mergesort(a, 0, 3, p);第一个数是a[0],第二个数是a[3],mid为1, 

first < last

递归调用左边:mergesort(a, 0, 1, p);右边:mergesort(a, 2, 3, p);

3::mergesort(a, 0, 1, p);第一个数是a[0],第二个数是a[1],mid为0, 

first < last

递归调用左边:mergesort(a, 0, 0, p);右边:mergesort(a, 1, 1, p);

4:左3:mergesort(a, 0, 0, p);第一个数是a[0],第二个数是a[0],mid为0, 

first = last,结束。

 右3:mergesort(a, 1, 1, p);第一个数是a[1],第二个数是a[1],mid为1, 

first = last,结束。

5:返回上一层开始进行合并,上一层first为0,last为1,mid为0,

依次类推,递归求解各个部分,最后再合并起来。

整个递归调用示意图如下图所示,递归调用最后一层first=last,结束递归调用返回上一层进行mergearray(a, first, mid, last, temp);将左右两个数组合并。


  • 时间复杂度为O(NlogN)归并排序很难用于主存排序,因为它在合并两个排序表时需要线性附加内存。
0 0