Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In my test this is 75% to %90 faster than array sort with the same System.Func comparer. I use it to sort a custom struct. you can easily modify it to sort classes.</p> <pre><code>public class DualQuickSort&lt;T&gt; where T : struct { private readonly System.Func&lt;T, T, int&gt; comparer; public DualQuickSort(System.Func&lt;T, T, int&gt; comparer) { this.comparer = comparer; } public DualQuickSort(IComparer&lt;T&gt; comparer) : this(comparer.Compare) { } public void Sort(T[] a) { Sort(a, 0, a.Length); } public void Sort(T[] a, int fromIndex, int toIndex) { RangeCheck(a.Length, fromIndex, toIndex); DualPivotQuicksort(a, fromIndex, toIndex - 1, 3); } private static void RangeCheck(int length, int fromIndex, int toIndex) { if (fromIndex &gt; toIndex) { throw new ArgumentException("fromIndex &gt; toIndex"); } if (fromIndex &lt; 0) { throw new IndexOutOfRangeException(fromIndex + " is less than 0"); } if (toIndex &gt; length) { throw new IndexOutOfRangeException(toIndex + " is greater than " + fromIndex); } } private static void Swap(T[] a, int i, int j) { var temp = a[i]; a[i] = a[j]; a[j] = temp; } private void DualPivotQuicksort(T[] a, int left, int right, int div) { var len = right - left; if (len &lt; 27) { // insertion sort for tiny array for (var i = left + 1; i &lt;= right; i++) { for (var j = i; j &gt; left &amp;&amp; comparer(a[j] , a[j - 1])==-1; j--) { Swap(a, j, j - 1); } } return; } var third = len / div; // "medians" var m1 = left + third; var m2 = right - third; if (m1 &lt;= left) { m1 = left + 1; } if (m2 &gt;= right) { m2 = right - 1; } if (comparer(a[m1] , a[m2])==-1) { Swap(a, m1, left); Swap(a, m2, right); } else { Swap(a, m1, right); Swap(a, m2, left); } // pivots var pivot1 = a[left]; var pivot2 = a[right]; // pointers var less = left + 1; var great = right - 1; // sorting for (var k = less; k &lt;= great; k++) { if (comparer(a[k] , pivot1)==-1) { Swap(a, k, less++); } else if (comparer(a[k], pivot2) == 1) { while (k &lt; great &amp;&amp; comparer(a[great] , pivot2)==1) { great--; } Swap(a, k, great--); if (comparer(a[k], pivot1) == -1) { Swap(a, k, less++); } } } // Swaps var dist = great - less; if (dist &lt; 13) { div++; } Swap(a, less - 1, left); Swap(a, great + 1, right); // subarrays DualPivotQuicksort(a, left, less - 2, div); DualPivotQuicksort(a, great + 2, right, div); // equal elements if (dist &gt; len - 13 &amp;&amp; comparer(pivot1,pivot2)!=0) { for (int k = less; k &lt;= great; k++) { if (comparer(a[k] , pivot1)==0) { Swap(a, k, less++); } else if (comparer(a[k], pivot2) == 0) { Swap(a, k, great--); if (comparer(a[k], pivot1) == 0) { Swap(a, k, less++); } } } } // subarray if (comparer(pivot1 , pivot2)==-1) { DualPivotQuicksort(a, less, great, div); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload