最近好不容易抽出点时间对《华容道》的程序做了番调整,发现程序的性能瓶颈居然在Array.Sort上面!经过调整后,程序运行时间缩短了1秒(河北石家庄李智广编写的华容道全能版V1.1第19关)!
微软的System.Array类提供了一个静态方法Sort,可以很方便的对一维数据进行排序。对于比较懒的我,一向直接使用Array.Sort完成对数组的排序。今天才发现原来Array.Sort存在严重的效率问题。先来看一段使用Array.Sort进行自定义排序的例子。
using System;
using System.Collections;
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
public class DataElement
{
public int value;
public DataElement() {}
public DataElement(int value) { this.value = value; }
}
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
public class DataElementComparer : IComparer
{
public int Compare(object x, object y)
{
return ((DataElement)x).value.CompareTo(((DataElement)y).value);
}
}
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
public class Client
{
public static void Main()
{
int[] a = {5,8,3,6,9};
DataElement[] d = new DataElement[5];
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for(int i=0; i<5; i++)
d[i] = new DataElement(a[i]);
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Array.Sort(d, new DataElementComparer());
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for(int i = 0; i<5; i++)
Console.Write(d[i].value + ", ");
}
}
注意,在上面的例子中,为了实现自定义类(DataElement)的排序,我设计了一个DataElementComparer类,实现了System.Collections.IComparer接口。这样,在应用Array.Sort方法时,同时提供要排序的数组以及DataElementComparer的一个实例,便可以进行排序了。
但需要注意的是,在.net 2003中没有泛型的支持,所以IComparer接口在定义时,Compare方法接收的参数是object类型。因此,在进行比较时需要对值类型数据进行反复Box和UnBox操作,而对于引用类型则反复进行UpCast和DownCast操作,严重影响了效率!
在C# 2.0规范中提供了泛型机制,我想IComparer接口应当重新进行了定义,Array.Sort的效率应当比现在要强很多。我后来将《华容道》中应用Array.Sort的地方改为了使用“快速排序法”代码,效率一下子上去了。解题时间从原来的7.4秒缩短到了6.4秒,可是不小的进步呀!快速排序法代码如下(具体算法可以参考《数据结构》中的相关章节):
using System;
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
public class DataElement
{
public int value;
public DataElement() {}
public DataElement(int value) { this.value = value; }
}
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
public class QuickSortArray
{
public DataElement[] list;
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void quickSort()
{
recQuickSort(0, list.Length - 1);
}
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void recQuickSort(int first, int last)
{
int pivotLocation;
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if(first < last)
{
pivotLocation = partition(first, last);
recQuickSort(first, pivotLocation - 1);
recQuickSort(pivotLocation + 1, last);
}
}
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private int partition(int first, int last)
{
DataElement pivot;
int index, smallIndex;
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
swap(first, (first + last) / 2);
pivot = list[first];
smallIndex = first;
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for(index = first + 1; index <= last; index++)
if(list[index].value < pivot.value)
{
smallIndex++;
swap(smallIndex, index);
}
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
swap(first, smallIndex);
return smallIndex;
}
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void swap(int first, int second)
{
DataElement temp;
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
temp = list[first];
list[first] = list[second];
list[second] = temp;
}
}
public class Client
{
public static void Main()
{
int[] a = {42, 43, 0, 1, 3, 20, 31, 32, 40, 41, 21, 23};
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
QuickSortArray qs = new QuickSortArray();
qs.list = new DataElement[12];
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for(int i=0; i<12; i++)
qs.list[i] = new DataElement(a[i]);
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
qs.quickSort();
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for(int i=0; i<12; i++)
Console.WriteLine(qs.list[i].value + ", ");
}
}
微软的System.Array类提供了一个静态方法Sort,可以很方便的对一维数据进行排序。对于比较懒的我,一向直接使用Array.Sort完成对数组的排序。今天才发现原来Array.Sort存在严重的效率问题。先来看一段使用Array.Sort进行自定义排序的例子。
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
注意,在上面的例子中,为了实现自定义类(DataElement)的排序,我设计了一个DataElementComparer类,实现了System.Collections.IComparer接口。这样,在应用Array.Sort方法时,同时提供要排序的数组以及DataElementComparer的一个实例,便可以进行排序了。
但需要注意的是,在.net 2003中没有泛型的支持,所以IComparer接口在定义时,Compare方法接收的参数是object类型。因此,在进行比较时需要对值类型数据进行反复Box和UnBox操作,而对于引用类型则反复进行UpCast和DownCast操作,严重影响了效率!
在C# 2.0规范中提供了泛型机制,我想IComparer接口应当重新进行了定义,Array.Sort的效率应当比现在要强很多。我后来将《华容道》中应用Array.Sort的地方改为了使用“快速排序法”代码,效率一下子上去了。解题时间从原来的7.4秒缩短到了6.4秒,可是不小的进步呀!快速排序法代码如下(具体算法可以参考《数据结构》中的相关章节):
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www2.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)