1.原則
としても知られている私たちの一般的なマージソートは、2路归并排序
2つのシーケンシャルリストまたはリンクリストを組み合わせる操作と同等です。長いシーケンステーブルを最小のサブシーケンスから最小のサブシーケンスに分割し、最小のサブシーケンスから大きなテーブルに徐々にマージするという二分法によってこれを実現すると、最終的な大きなテーブルが順序付けられます。
したがって、これは時間計算量がnlog 2 nnlog_2nの再帰的プロセスです。n l o g2n
2.プロセス
再帰的なプロセスなので、一緒に表示する方が便利です
順序付きリストの要素が0からnまでのn + 1要素であるとします。ここで、開始はlを表し、終了はhを表し、中央の要素はm =(l + h)/ 2で表されます。
再帰式は次のことができます。次のように記述します:
sort(l、h)= {l = h、再帰的終了l <h、sort(l、m); sort(m + 1、h);およびmerge sort(l、h)= \ begin(ケース)l = h、&再帰的終了\\ l <h、&sort(l、m); sort(m + 1、h);およびマージ\\ \ end(cases)s o r t (l 、h )={{
l=h 、l<時間、手は行く最後のストップをs o r t (l 、m );s o r t (m+1 、h );そして閉じて
3.コード
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 100
int temp[MAXLEN] = {
0}; //创建一个临时变量数组
int Mergelist(int arry[], int low, int mid,int high)
{
int tptr, lptr, hptr, i = 0;
tptr = 0; // 临时数组储存下标
lptr = low; // 左序列下标,low<=lptr<=mid
hptr = mid + 1; // 右序列下标,mid+1<=hptr<=high
while(lptr <= mid && hptr <= high) // 这三个while就是循环合并两个线性表
{
// 将左序列或右序列中,较小的存入临时数组里
if (arry[lptr] <= arry[hptr])
{
temp[tptr] = arry[lptr];
++lptr;
}
else
{
temp[tptr] = arry[hptr];
++hptr;
}
++tptr;
}
// 检测左序列是否添加完毕
while(lptr <= mid)
{
temp[tptr] = arry[lptr];
++lptr;
++tptr;
}
// 检测右序列是否添加完毕
while(hptr <= high)
{
temp[tptr] = arry[hptr];
++hptr;
++tptr;
}
// 将新序列覆盖原数组
for (; i < tptr; ++i)
{
arry[low+i]=temp[i];
}
}
int MergeSort(int arry[], int low, int high)
{
int mid;
if (low < high) // 可递归部分
{
mid = (low + high) / 2;
MergeSort(arry, low, mid); // 左序列
MergeSort(arry, mid+1, high); // 右序列
Mergelist(arry, low, mid, high); // 合并两序列
}
}
int main()
{
int a[7] = {
6,5,3,7,2,1,4};
int i;
MergeSort(a, 0, 6);
for (i = 0; i < 7; ++i)
{
printf("%d ", a[i]);
}
return 0;
}