[英]Quicksort algorithm (C#)
我想问一下这段代码实际上有什么问题。 我试图自己理解quicksort(2-way),所以我浏览了以下页面: http : //me.dt.in.th/page/Quicksort/#disqus_thread之后,我尝试自己对其进行编码并落入此处:
public void Sort(Comparison<TList> del, long l, long r)
{
// inspired by: http://me.dt.in.th/page/Quicksort/
if (l >= r) return;
// partitioning
for(long i = l + 1; i <= r; i++)
{
if (del.Invoke(this[i], this[l]) < 0)
{
Swap(i, l);
}
}
// recursion
Sort(del, l, l - 1);
Sort(del, l + 1, r);
}
然后,我调查了提到的网站上的评论,发现了这一点:
void qsort(char *v[], int left, int right)
{
int i, last;
void swap(char *v[], int i, int j);
if (left >= right)
return;
swap(v, left, (left + right) / 2);
last = left;
for (i = left + 1; i <= right; i++)
if (strcmp(v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
qsort(v, left, last - 1);
qsort(v, last + 1, right);
}
现在我真的很好奇为什么我的代码仍然可以正常工作,对此进行了测试(顺便说一句,它包含在链接列表中):
static void Main(string[] args)
{
MyList<int> obj;
do
{
obj = MyList.Random(100, 0, 100);
obj.Sort(stdc);
obj.Sort(stdc);
} while (obj.IsSorted(stdc));
Log("Not sorted", obj);
Console.ReadKey(true);
}
和这个:
public bool IsSorted(Comparison<TList> del)
{
var el = start;
if (el != null)
{
while (el.Next != null)
{
if (del.Invoke(el.Value, el.Next.Value) > 0) // eq. to this[i] > this[i + 1]
return false;
el = el.Next;
}
}
return true;
}
和这个:
public static MyList<int> Random(int num, int min = 0, int max = 1)
{
var res = new MyList<int>();
var rand = new Random();
while (num > 0)
{
res.Add(rand.Next(min, max));
num--;
}
return res;
}
您的quicksort代码不是真正的quicksort,它会很慢。 线
Sort(del, l, l - 1);
不会执行任何操作,因为递归调用会检测到l> =(l-1)。 线
Sort(del, l + 1, r);
仅将分区[l,r]的大小减小1到[l + 1,r],所以时间复杂度将始终为O(n ^ 2),但看起来它将起作用,只是速度很慢。
qsort()函数交换左值和中间值,如果已对数据进行排序,但不会做其他很多事情,这将避免最坏情况的问题。 关键是它会更新“ last”,以便在分区完成后,v [last]处的值将成为枢轴值,然后使用“ last”而不是“ left”或在您的代码中进行递归调用,“ l”。
所示的qsort是Lomuto分区方案的变体。 看一下Wiki文章,其中还包括备用的Hoare分区方案:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.