第四周:归并算法
归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为:
1)划分子表
2)合并半子表
/// <summary>
/// 归并排序之归:归并排序入口
/// Updated by Lihua at 05/06/2009
/// </summary>
/// <param name="data">无序数组</param>
/// <returns>有序数组</returns>
/// <author>lihua</author>
/// <copyright>www.zivsoft.com</copyright>
static int[] Sort(int[] data)
{
//若data为null,或只剩下1 or 0个元素,返回,不排序
if (null == data || data.Length <= 1)
{
return data;
}
//取数组中间下标
//int middle = data.Length / 2; //方法一:除2取整数
int middle = data.Length >> 1; //方法二:位移 (感谢读者hyper给出的这个效率稍高的方法)
//初始化临时数组let,right,并定义result作为最终有序数组,若数组元素奇数个,将把多余的那元素空间预留在right临时数组
int[] left = new int[middle], right = new int[data.Length - middle], result = new int[data.Length];
//经调查,用Array.Copy的确比上面的for循环优化很多
Array.Copy(data, 0, left, 0, middle);//拷贝左数组
Array.Copy(data, left.Length, right, 0, right.Length); //拷贝右数组
left = Sort(left);//递归左数组
right = Sort(right);//递归右数组
result = Merge(left, right);//开始排序
//this.Write(result);//输出排序,测试用(lihua debug)
return result;
}
/// <summary>
/// 归并排序之并:排序在这一步
/// </summary>
/// <param name="a">左数组</param>
/// <param name="b">右数组</param>
/// <returns>合并左右数组排序后返回</returns>
static int[] Merge(int[] a, int[] b)
{
//定义结果数组,用来存储最终结果
int[] result = new int[a.Length + b.Length];
int i = 0, j = 0, k = 0;
while (i < a.Length && j < b.Length)
{
if (a[i] < b[j])//左数组中元素小于右数组中元素
{
result[k++] = a[i++];//将小的那个放到结果数组
}
else//左数组中元素大于右数组中元素
{
result[k++] = b[j++];//将小的那个放到结果数组
}
}
while (i < a.Length)//这里其实是还有左元素,但没有右元素
{
result[k++] = a[i++];
}
while (j < b.Length)//右右元素,无左元素
{
result[k++] = b[j++];
}
return result;//返回结果数组
}
主要参考来源: http://www.cnblogs.com/architect/archive/2009/05/06/1450489.html

浙公网安备 33010602011771号