快速排序,是否正确?求帮助!

SuperTyro 2011-07-27 03:13:41
下面是一个个人从网上找到的快速排序算法,不过原文是c++ 版本的,本人将其翻译成了C#版本,请教大侠指点是否正确,
并指出问题所在!
可以先尝试用自己生成的测试数组尝试排序。
在尝试算法的时候请忽视我提供的测试数据,以便于查看算法是否有问题!
得到结果后,请使用int[] arr = { 1, 5, 4, 3, 1, 2, 456, 1, 32, 2 };再次进行测试。

求指点!

[code=c#]
public class SuperQuickSort
{
private void Swap(int [] arr , int x , int y)
{
if (arr[x] > arr[y])
{
arr[x] = arr[x] + arr[y];
arr[y] = arr[x] - arr[y];
arr[x] = arr[x] - arr[y];
}
}

public void QuickSort(int [] arr, int left , int right)
{
do
{
int a = left;
int b = right;
int c = left + ((right - left) >> 1);

Swap(arr, a, b);
Swap(arr, a, c);
Swap(arr, c, b);

do
{
while (arr[a] < arr[c])
{
a++;
}
while (arr[c] < arr[b])
{
b--;
}
if (a > b)
{
break;
}
if (a < b)
{
Swap(arr,a,b);
}
a++;
b--;
} while (a <= b);

if ((right - a) >= (b - left))
{
if (b > left)
{
QuickSort(arr, left, b);
}
left = a;

}
else
{

if (right > a)
{
QuickSort(arr, a, right);
}
right = b;

}

} while (left < right);
}
}
[/code]
...全文
329 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
vrhero 2011-07-28
  • 打赏
  • 举报
回复
都是快排算法,为什么差异这么大...因为算法只是其中一个步骤甚至只是一小步骤...

数组对象非常简单,在调用Sort方法时几乎没有其他开销...而泛型接口对象则需要根据集合类型重新整理其内部数组甚至重新生成数组对象并复制元素,这部分的开销远远大于快排算法...

但这是工程化必须承受的代价...
renyiqiu 2011-07-28
  • 打赏
  • 举报
回复
不错,感觉还是要懂下原理才行,微软就是太懂得照顾人,什么都为你安排好
showjim 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 supertyro 的回复:]
引用 24 楼 sbwwkmyd 的回复:
汗!难道List.Sort不是调用的Array.Sort?


Array.Sort()
http://msdn.microsoft.com/zh-cn/library/6tf1f0bc(v=VS.80).aspx
List<T>.Sort()
http://msdn.microsoft.com/zh-cn/library/b0zbh7b6……
[/Quote]
可以看看这个
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
感谢 25楼的帮助
我这就去试试,并尝试修改我的方法。

稍后会给出结果。
showjim 2011-07-28
  • 打赏
  • 举报
回复
而List.Sort调用的Array.Sort<T>是基于接口IComparer<T>的函数调用比较,所以会比非泛型的慢
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 sbwwkmyd 的回复:]
汗!难道List.Sort不是调用的Array.Sort?
[/Quote]

Array.Sort()
http://msdn.microsoft.com/zh-cn/library/6tf1f0bc(v=VS.80).aspx
List<T>.Sort()
http://msdn.microsoft.com/zh-cn/library/b0zbh7b6.aspx

MSDN的描述中对于实用的排序算法的描述是一致的,但是依据其测试结果数据,个人判断内部实现还是有不一样的地方的(哪怕是解释期间会有不同)

但仍然希望了解些更深入的部分,如为何Array.Sort如此之快,是如何实现的。
希望vrhero能给些指导。
不胜感激。
showjim 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 supertyro 的回复:]
抱歉我理解过了你表达的方式。
刚刚试用Array.Sort进行了一下测试 消耗在 100+左右

请教下vrhero,Array.Sort如此之快,内部是如何实现的呢?MSDN描述的并不足够深入。[/Quote]
可以用Reflector看到Array.Sort实现的QuickSort
void QuickSort(int left, int right)
{
do
{
int low = left;
int hi = right;
int median = Array.GetMedian(low, hi);
this.SwapIfGreaterWithItems(low, median);
this.SwapIfGreaterWithItems(low, hi);
this.SwapIfGreaterWithItems(median, hi);
object y = this.keys.GetValue(median);
do
{
try
{
while (this.comparer.Compare(this.keys.GetValue(low), y) < 0)
{
low++;
}
while (this.comparer.Compare(y, this.keys.GetValue(hi)) < 0)
{
hi--;
}
}
catch (IndexOutOfRangeException)
{
throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", new object[] { y, y.GetType().Name, this.comparer }));
}
catch (Exception exception)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), exception);
}
catch
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"));
}
if (low > hi)
{
break;
}
if (low < hi)
{
object obj3 = this.keys.GetValue(low);
this.keys.SetValue(this.keys.GetValue(hi), low);
this.keys.SetValue(obj3, hi);
if (this.items != null)
{
object obj4 = this.items.GetValue(low);
this.items.SetValue(this.items.GetValue(hi), low);
this.items.SetValue(obj4, hi);
}
}
if (low != 0x7fffffff)
{
low++;
}
if (hi != -2147483648)
{
hi--;
}
}
while (low <= hi);
if ((hi - left) <= (right - low))
{
if (left < hi)
{
this.QuickSort(left, hi);
}
left = low;
}
else
{
if (low < right)
{
this.QuickSort(low, right);
}
right = hi;
}
}
while (left < right);
}
showjim 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 vrhero 的回复:]你知道什么是“Array.Sort”吗?不知道去看MSDN...[/Quote]
汗!难道List.Sort不是调用的Array.Sort?
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 vrhero 的回复:]

你知道什么是“Array.Sort”吗?不知道去看MSDN...
[/Quote]

抱歉我理解过了你表达的方式。
刚刚试用Array.Sort进行了一下测试 消耗在 100+左右

请教下vrhero,Array.Sort如此之快,内部是如何实现的呢?MSDN描述的并不足够深入。
chenwei9120 2011-07-28
  • 打赏
  • 举报
回复
练一下也好,不过也要知道.net自带的排序方法.
vrhero 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 supertyro 的回复:]
引用 17 楼 vrhero 的回复:

测试方法都不对...你的方法用数组去跟Linq那么大型的泛型框架比...有本事去跟Array.Sort比...


以上确实有和Array.Sort的比较结果

以上我提供的代码 消耗的 sw.ElapsedTicks 为1040+

arr.ToList().Sort(); 为 3600+
[/Quote]
你知道什么是“Array.Sort”吗?不知道去看MSDN...
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 qq81867376 的回复:]

可是话又说回来,当你在公司工作的话,你会发现你能满足需求的要求,你就不想去那么注意的了, 没有办法是必出来的,工作的中很多这样的,原来是有很厚兴趣,后来就完成任务。
[/Quote]

谢谢你的回复。

我只是希望我的代码能够更优秀,哪怕只是一点点的结构优化或性能的提升。
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 vrhero 的回复:]

测试方法都不对...你的方法用数组去跟Linq那么大型的泛型框架比...有本事去跟Array.Sort比...
[/Quote]

以上确实有和Array.Sort的比较结果

以上我提供的代码 消耗的 sw.ElapsedTicks 为1040+

arr.ToList().Sort(); 为 3600+
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 vrhero 的回复:]

哪儿来的值类型?

这个开销就像那艘废旧航母的开销远远大于亚丁湾那几支先进舰队一样...不是因为那些先进舰队便宜,也不是因为废旧航母个头大,而是因为废旧航母的配套太多...而加上那些配套废旧航母能做的事那几支先进舰队却不可能做到,或者就算能做到但在其他地方的开销将会远远大于废旧航母...

这是哲学工程学问题,与技术细节无关...不过.NET造好了轮子,我没把握造出比它更好的轮子的情况下……
[/Quote]

感谢您的回复,不过我仍然想弄清我的算法到底问题在哪里,也许性能不会比Array.Sort快
但至少希望他是正确的。
至少希望知道25楼给出的代码是Reflector来的,为什么用我的测试数据来做仍然有问题。
showjim 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 supertyro 的回复:]
经过测试使用25楼的代码对下列数组并不能完全排序
int[] arr = { 1, 5, 4, 3, 1, 2, 456, 1, 32, 2 };

To sbwwkmyd:如果你有兴趣可以尝试变异你的代码并用我提供的这组数组作为测试数据尝试一下。
[/Quote]
那是.net里面的快排,不是我的代码。
我表示没有这个兴趣测试它的正确性。
vrhero 2011-07-28
  • 打赏
  • 举报
回复
哪儿来的值类型?

这个开销就像那艘废旧航母的开销远远大于亚丁湾那几支先进舰队一样...不是因为那些先进舰队便宜,也不是因为废旧航母个头大,而是因为废旧航母的配套太多...而加上那些配套废旧航母能做的事那几支先进舰队却不可能做到,或者就算能做到但在其他地方的开销将会远远大于废旧航母...

这是哲学工程学问题,与技术细节无关...不过.NET造好了轮子,我没把握造出比它更好的轮子的情况下就绝不会浪费时间去造无用的破轮子...
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 vrhero 的回复:]

都是快排算法,为什么差异这么大...因为算法只是其中一个步骤甚至只是一小步骤...

数组对象非常简单,在调用Sort方法时几乎没有其他开销...而泛型接口对象则需要根据集合类型重新整理其内部数组甚至重新生成数组对象并复制元素,这部分的开销远远大于快排算法...

但这是工程化必须承受的代价...
[/Quote]

请教:请问我是否可以把这部分的开销区别理解为值类型和引用类型的变量的应用性能消耗上?
SuperTyro 2011-07-28
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 sbwwkmyd 的回复:]
可以用Reflector看到Array.Sort实现的QuickSort
C# code
void QuickSort(int left, ……
[/Quote]

经过测试使用25楼的代码对下列数组并不能完全排序
int[] arr = { 1, 5, 4, 3, 1, 2, 456, 1, 32, 2 };

To sbwwkmyd:如果你有兴趣可以尝试变异你的代码并用我提供的这组数组作为测试数据尝试一下。
jeje 2011-07-27
  • 打赏
  • 举报
回复
关注....
vrhero 2011-07-27
  • 打赏
  • 举报
回复
测试方法都不对...你的方法用数组去跟Linq那么大型的泛型框架比...有本事去跟Array.Sort比...
加载更多回复(16)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧