这几天事情不多,回顾一下排序算法。过去虽然也练习过,可现在发现,要重写一遍,不是IndexOutOfRange就是StackOverFlow,反正基本得不到正确结果。让偶情何以堪?
这些简单的排序算法程序应该不需要什么编程功底,写不对的真正原因,还是没有理解算法。以前写的算法代码,一看就不像出自本人,繁琐而缺乏美感,更重要的是边界处理基本是靠瞎朦的,碰对了就行。写算法代码本来应该是极其严谨的过程,这样子不会得到丝毫提高的。
于是,偶这两天一直就钻研一个普通的不能再普通的快速排序,不断尝试修改一些实现细节,测试结果正确性和时间性能。终于,昨天得到了一个个人认为最简洁,最富美感、最能体现算法思想的实现,一定要分享,先贴出代码:
///
<summary>
/// 最简洁的快速排序
/// </summary>
/// <typeparam name="T"> 可比较的类型 </typeparam>
/// <param name="array"> 待排序数组 </param>
/// <param name="start"> 数组起始索引 </param>
/// <param name="end"> 数组末尾索引 </param>
internal static void QuickSort < T > (T[] array, int start, int end) where T : IComparable < T >
{
var left = start;
var right = end;
var middle = array[start];
while ( true )
{
while (array[right].CompareTo(middle) > 0 ) right -- ;
if (right == left) break ;
Swap(array, left ++ , right);
while (array[left].CompareTo(middle) < 0 ) left ++ ;
if (right == left) break ;
Swap(array, left, right -- );
}
if (left - start > 1 ) QuickSort(array, start, left - 1 ); // 如子区间块长大于1,则继续对区间排序
if (end - left > 1 ) QuickSort(array, left + 1 , end);
}
/// <summary>
/// 交换数组中两个索引对应的元素
/// </summary>
static void Swap < T > (T[] array, int n1, int n2)
{
var temp = array[n1];
array[n1] = array[n2];
array[n2] = temp;
}
/// 最简洁的快速排序
/// </summary>
/// <typeparam name="T"> 可比较的类型 </typeparam>
/// <param name="array"> 待排序数组 </param>
/// <param name="start"> 数组起始索引 </param>
/// <param name="end"> 数组末尾索引 </param>
internal static void QuickSort < T > (T[] array, int start, int end) where T : IComparable < T >
{
var left = start;
var right = end;
var middle = array[start];
while ( true )
{
while (array[right].CompareTo(middle) > 0 ) right -- ;
if (right == left) break ;
Swap(array, left ++ , right);
while (array[left].CompareTo(middle) < 0 ) left ++ ;
if (right == left) break ;
Swap(array, left, right -- );
}
if (left - start > 1 ) QuickSort(array, start, left - 1 ); // 如子区间块长大于1,则继续对区间排序
if (end - left > 1 ) QuickSort(array, left + 1 , end);
}
/// <summary>
/// 交换数组中两个索引对应的元素
/// </summary>
static void Swap < T > (T[] array, int n1, int n2)
{
var temp = array[n1];
array[n1] = array[n2];
array[n2] = temp;
}
它的改进在哪里,就是简洁。首先,易记易理解。就是数组的一段区间,分别从两端逐渐靠陇,向前和向后靠拢是对称的。其次,该实现 因为简洁往往意味着合理,合理往往带来高效。经过测试,这也是目前快速排序效率最高的方式。