归并排序(Merge-Sort)
归并排序是以分而治之的思想,将数据分开、分别比较两边的值,并用一个辅助的数组去存储比较后的结果。
代码是用递归来实现,将一段数组切分为两段,再对两段进行Merge操作。
class Test{
static void Main(string[] args)
{
int[] a = new int[] { 3, 2, 1, 5, 4, 2 };
Sort(a, 0, a.Length - 1);
foreach(int temp in a)
{
Console.WriteLine(temp);
}
}
//归并排序
public static void Sort(int[] arr,int l,int r)
{
if (l == r) return;
int mid = l + ((r - l) >> 1);
Sort(arr, l,mid);
Sort(arr, mid + 1, r);
Merge(arr, l,mid, r);
}
这里Sort里面的mid = l + ((r-l) >> 1) 是防止int的溢出问题。
一般我们求中位数是 (l + r)/ 2 但是有可能l+r 会超过int上限,导致结果出错,所以用以上写法可以防止数据溢出。
merge就是通过传入的参数 l 和 r定义一个长度为 r - l 的数组来存储这次排序之后的数组状态
这次排序是根据数组arr的中点 mid 来吧arr数组分成两个部分,并定义两个游标p1,p2来遍历比较两段数组数据大小。
代码如下:
public static void Merge(int[] arr,int l,int mid,int r)
{
int[] a = new int[r-l+1];
int i = 0;
int p1 = l;
int p2 = mid + 1;
while (p1<= mid && p2<=r)
{
//两个游标都在区间内 哪个小就计入辅助空间 游标右移
a[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= mid)
{
a[i++] = arr[p1++];
}
while (p2 <= r)
{
a[i++] = arr[p2++];
}
for(i = 0; i < a.Length; i++)
{
//区间最左开始数 不一定是0
arr[l+i] = a[i];
}
}
注意定义r-l长度的数组要从0到r-l+1。
第一次写博客,不会排版。(黑历史,GET DAZE!)