归并排序

王朝百科·作者佚名  2009-11-09
窄屏简体版  字體: |||超大  

归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。最简单的归并是直接将两个有序的子表合并成一个有序的表。

在内部排序中,通常采用的是2-路归并排序。即:将两个位置相邻的记录有序子序列归并为一个记录的有序序列。

每一趟归并的时间复杂度为 O(n)

在插入排序,选择排序,快速排序,归并排序这几种排序中,要求内存量最大的是归并排序。

F. 归并排序

{a为序列表,tmp为辅助数组}

procedure merge(var a:listtype; p,q,r:integer);

{将已排序好的子序列a[p..q]与a[q+1..r]合并为有序的tmp[p..r]}

var I,j,t:integer;

tmp:listtype;

begin

t:=p;i:=p;j:=q+1;{t为tmp指针,I,j分别为左右子序列的指针}

while (t<=r) do begin

if (i<=q){左序列有剩余} and ((j>r) or (a<=a[j])) {满足取左边序列当前元素的要求}

then begin

tmp[t]:=a; inc(i);

end

else begin

tmp[t]:=a[j];inc(j);

end;

inc(t);

end;

for i:=p to r do a:=tmp;

end;{merge}

procedure merge_sort(var a:listtype; p,r: integer); {合并排序a[p..r]}

var q:integer;

begin

if p<>r then begin

q:=(p+r-1) div 2;

merge_sort (a,p,q);

merge_sort (a,q+1,r);

merge (a,p,q,r);

end;

end;

{main}

begin

merge_sort(a,1,n);

end.

C#的实现:

class MergeSort

{

public MergeSort()

{ }

public int[] Sort(int[] data)

{

Merge_Sort(data, 0, data.Length - 1);

return data;

}

private void Merge_Sort(int[] data, int first, int last)

{

int mid = 0;

if (first < last)

{

mid = (first + last) / 2;

Merge_Sort(data, first, mid);

Merge_Sort(data, mid + 1, last);

Merge(data, first, mid, last);

}

}

private void Merge(int[] data, int first, int mid, int last)

{

int[] temp = new int[last-first+1];

int begin1, begin2, end1, end2;

int index = 0;

begin1 = first;

begin2 = mid + 1;//这里很重要,如果换成begin2 = mid ;end1 = mid -1;结果将完全不对;

end1 = mid;

end2 = last;

while ((begin1 <= end1) && (begin2 <= end2))

{

if (data[begin1] > data[begin2])

temp[index] = data[begin1++];

else

temp[index] = data[begin2++];

index++;

}

while (begin1 <= end1)

temp[index++] = data[begin1++];

while (begin2 <= end2)

temp[index++] = data[begin2++];

for (int i =0,k = first; k <= last; k++,i++)

data[k] = temp[i];

}

}

我的归并排序代码注:ar为待排序数组,tar为与ar等大的临时数组。mg_sort会把ar数组中下标在[f..t-1]之内的元素排序。

void mg_sort(int f,int t,int *ar,int *tar) {

if(f+1<t) {

int m,i,j,k;

m=(f+t)/2;

memcpy(tar+f,ar+f,(t-f)*sizeof(int));

mg_sort(f,m,tar,ar);

mg_sort(m,t,tar,ar);

i=f;

j=m;

k=f;

while(i<m && j<t)

ar[k++]= tar[i]>=tar[j] ? tar[i++]:tar[j++] ;

while(i<m)

ar[k++]=tar[i++];

while(j<t)

ar[k++]=tar[j++];

}

}

C语言完整实现

#include <stdio.h>

#include <stdlib.h>

#include <iostream.h >

void merge(int array[], int p, int q, int r)

{

int* temp = new int [r-p+1]; //申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

int m=p;

int n=q+1;

int k = 0;

while((m<=q)&&( n<=r)) //比较两个下标所指向的元素,选择相对小的元素放入到合并空间,并移动下标到下一位置

{

if(array[m]<array[n])

{

temp[k] = array[m];

m++;

}

else

{

temp[k] = array[n];

n++;

}

k++;

}

while(m<=q) //若第一个序列有剩余,直接拷贝出来粘到合并序列尾

{

temp[k] = array[m];

k++;

m++;

}

while(n<=r) //若第二个序列有剩余,直接拷贝出来粘到合并序列尾

{

temp[k] = array[n];

k++;

n++;

}

for (int i = 0; i < (r - p +1); i++) //将排序好的序列拷贝回数组中

{

array[p+i] = temp[i];

}

}

void mergesort(int A[],int p,int r)

{

if (p<r)

{

int q = (p+r)/2;

mergesort(A,p,q);

mergesort(A,q+1,r);

merge(A,p,q,r);

}

}

int main()

{

int A[9]={9,3,6,1,4,7,2,8,5};

mergesort(A,0,8);

for (int i = 0; i < 9; i++) //打印数组

{

cout<<A[i] ;

}

return 1;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航