归并排序

View Code
  1 class Program
  2     {
  3         static void Main(string[] args)
  4         {
  5             int[] data = new int[] { 21, 37, 12, 56, 11, 78, 65, 96 };
  6             data = Sort(data);
  7             foreach (int a in data)
  8             {
  9                 Console.WriteLine(a.ToString());
 10             }
 11         }
 12         /// <summary>
 13         /// 归并排序之归:归并排序入口 
 14         /// Updated by Lihua at 05/06/2009
 15         /// </summary>
 16         /// <param name="data">无序数组</param>
 17         /// <returns>有序数组</returns>
 18         /// <author>lihua</author>
 19         /// <copyright>www.zivsoft.com</copyright>
 20         static int[] Sort(int[] data)
 21         {
 22             //若data为null,或只剩下1 or 0个元素,返回,不排序
 23             if (null == data || data.Length <= 1)
 24             {
 25                 return data;
 26             }
 27 
 28             //取数组中间下标
 29             //int middle = data.Length / 2; //方法一:除2取整数
 30             int middle = data.Length >> 1;  //方法二:位移 (感谢读者hyper给出的这个效率稍高的方法)
 31 
 32             //初始化临时数组let,right,并定义result作为最终有序数组,若数组元素奇数个,将把多余的那元素空间预留在right临时数组
 33             int[] left = new int[middle], right = new int[data.Length - middle], result = new int[data.Length];
 34 
 35             //下面这句对性能有些影响,所以在上面有了改进,直接用data.Length-middle初始化right数组
 36             //if (data.Length % 2 != 0) right = new int[middle + 1]; 
 37 
 38             //int i = 0, j = 0;
 39             //foreach (int x in data)//开始排序
 40             //{
 41             //    if (i < middle)//填充左数组
 42             //    {
 43             //        left[i] = x;
 44             //        i++;
 45             //    }
 46             //    else//填充右数组
 47             //    {
 48             //        right[j] = x;
 49             //        j++;
 50             //    }
 51             //}
 52 
 53             //上面的foreach被改成了for循环
 54             //for (int i = 0; i < data.Length; i++)
 55             //{
 56             //    if (i < middle)//用middle,不用left.Length
 57             //    {
 58             //        left[i] = data[i];
 59             //    }
 60             //    else
 61             //    {
 62             //        right[i - middle] = data[i]; //此处i-middle,让我省掉定义一个j,性能有所提高
 63             //    }
 64             //}
 65 
 66             //经调查,用Array.Copy的确比上面的for循环优化很多
 67             Array.Copy(data, 0, left, 0, middle);//拷贝左数组
 68             Array.Copy(data, left.Length, right, 0, right.Length); //拷贝右数组
 69             
 70             left = Sort(left);//递归左数组
 71             right = Sort(right);//递归右数组
 72             result = Merge(left, right);//开始排序
 73             //this.Write(result);//输出排序,测试用(lihua debug)
 74             return result;
 75         }
 76         /// <summary>
 77         /// 归并排序之并:排序在这一步
 78         /// </summary>
 79         /// <param name="a">左数组</param>
 80         /// <param name="b">右数组</param>
 81         /// <returns>合并左右数组排序后返回</returns>
 82         static int[] Merge(int[] a, int[] b)
 83         {
 84             //定义结果数组,用来存储最终结果
 85             int[] result = new int[a.Length + b.Length];
 86             int i = 0, j = 0, k = 0;
 87             while (i < a.Length && j < b.Length)
 88             {
 89                 if (a[i] < b[j])//左数组中元素小于右数组中元素
 90                 {
 91                     result[k++] = a[i++];//将小的那个放到结果数组
 92                 }
 93                 else//左数组中元素大于右数组中元素
 94                 {
 95                     result[k++] = b[j++];//将小的那个放到结果数组
 96                 }
 97             }
 98             while (i < a.Length)//这里其实是还有左元素,但没有右元素
 99             {
100                 result[k++] = a[i++];
101             }
102             while (j < b.Length)//右右元素,无左元素
103             {
104                 result[k++] = b[j++];
105             }
106             return result;//返回结果数组
107         }
108 
109     }
posted @ 2012-08-01 15:18  有态度的80后  阅读(189)  评论(0编辑  收藏  举报