合并排序(MERGE SORT)是又一类不同的排序方法,合并的含义就是将两个或两个以上的有序数据序列合并成一个新的有序数据序列,因此它又叫归并算法。它的基本思想就是假设数组A有N个元素,那么可以看成数组A是又N个有序的子序列组成,每个子序列的长度为1,然后再两两合并,得到了一个 N/2 个长度为2或1的有序子序列,再两两合并,如此重复,值得得到一个长度为N的有序数据序列为止,这种排序方法称为2—路合并排序。
例如数组A有7个数据,分别是: 49 38 65 97 76 13 27,那么采用归并排序算法的操作过程如图7所示:
初始值 [49] [38] [65] [97] [76] [13] [27]
看成由长度为1的7个子序列组成
第一次合并之后 [38 49] [65 97] [13 76] [27]
看成由长度为1或2的4个子序列组成
第二次合并之后 [38 49 65 97] [13 27 76]
看成由长度为4或3的2个子序列组成
第三次合并之后 [13 27 38 49 65 76 97]
图6 归并排序算法过程图
合并算法的核心操作就是将一维数组中前后相邻的两个两个有序序列合并成一个有序序列。合并算法也可以采用递归算法来实现,形式上较为简单,但实用性很差。
合并算法的合并次数是一个非常重要的量,根据计算当数组中有3到4个元素时,合并次数是2次,当有5到8个元素时,合并次数是3次,当有9到16个元素时,合并次数是4次,按照这一X规律,当有N个子序列时可以推断出合并的次数是X(2 >=N,符合此条件的最小那个X)。
源程序:
例如数组A有7个数据,分别是: 49 38 65 97 76 13 27,那么采用归并排序算法的操作过程如图7所示:
初始值 [49] [38] [65] [97] [76] [13] [27]
看成由长度为1的7个子序列组成
第一次合并之后 [38 49] [65 97] [13 76] [27]
看成由长度为1或2的4个子序列组成
第二次合并之后 [38 49 65 97] [13 27 76]
看成由长度为4或3的2个子序列组成
第三次合并之后 [13 27 38 49 65 76 97]
图6 归并排序算法过程图
合并算法的核心操作就是将一维数组中前后相邻的两个两个有序序列合并成一个有序序列。合并算法也可以采用递归算法来实现,形式上较为简单,但实用性很差。
合并算法的合并次数是一个非常重要的量,根据计算当数组中有3到4个元素时,合并次数是2次,当有5到8个元素时,合并次数是3次,当有9到16个元素时,合并次数是4次,按照这一X规律,当有N个子序列时可以推断出合并的次数是X(2 >=N,符合此条件的最小那个X)。
源程序:
program hebing;
const
n=10;
var
a:array[1..n] of integer;
i:integer;
procedure init;
var
i:integer;
begin
for i:=1 to n do read(a[i]);
readln;
end;
procedure merge(low,mid,high:integer);
var
h,i,j,k:integer;
b:array[1..n] of integer;
begin
h:=low; i:=low; j:=mid+1;
while (h<=mid) and (j<=high) do begin
if (a[h]<=a[j]) then begin
b[i]:=a[h]; h:=h+1;
end else begin
b[i]:=a[j]; j:=j+1;
end;
i:=i+1;
end;
if h>mid then
for k:=j to high do begin
b[i]:=a[k]; i:=i+1;
end else
for k:=h to mid do begin
b[i]:=a[k]; i:=i+1;
end;
for k:=low to high do a[k]:=b[k];
end;
procedure mergesort(low,high:integer);
var
mid:integer;
begin
if low<high then begin
mid:=(low+high) div 2;
mergesort(low,mid);
mergesort(mid+1,high);
merge(low,mid,high);
end;
end;
const
n=10;
var
a:array[1..n] of integer;
i:integer;
procedure init;
var
i:integer;
begin
for i:=1 to n do read(a[i]);
readln;
end;
procedure merge(low,mid,high:integer);
var
h,i,j,k:integer;
b:array[1..n] of integer;
begin
h:=low; i:=low; j:=mid+1;
while (h<=mid) and (j<=high) do begin
if (a[h]<=a[j]) then begin
b[i]:=a[h]; h:=h+1;
end else begin
b[i]:=a[j]; j:=j+1;
end;
i:=i+1;
end;
if h>mid then
for k:=j to high do begin
b[i]:=a[k]; i:=i+1;
end else
for k:=h to mid do begin
b[i]:=a[k]; i:=i+1;
end;
for k:=low to high do a[k]:=b[k];
end;
procedure mergesort(low,high:integer);
var
mid:integer;
begin
if low<high then begin
mid:=(low+high) div 2;
mergesort(low,mid);
mergesort(mid+1,high);
merge(low,mid,high);
end;
end;