[英]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.